From d12d56a83bc2e91f31a7d8d5ad3e97bab636c9f3 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 4 Jun 2026 18:56:51 +0100 Subject: [PATCH 01/12] chore: rename agent_instructions to bot_directives for spec alignment --- .../{agent_instructions => bot_directives}/README.adoc | 2 +- .../{agent_instructions => bot_directives}/coverage.a2ml | 0 .../{agent_instructions => bot_directives}/debt.a2ml | 0 .../methodology.a2ml | 0 .well-known/ai.txt | 2 +- 0-AI-MANIFEST.a2ml | 8 ++++---- FAQ.adoc | 2 +- QUICKSTART-DEV.adoc | 2 +- docs/audits/2026-06-01-deep-audit.adoc | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) rename .machine_readable/{agent_instructions => bot_directives}/README.adoc (95%) rename .machine_readable/{agent_instructions => bot_directives}/coverage.a2ml (100%) rename .machine_readable/{agent_instructions => bot_directives}/debt.a2ml (100%) rename .machine_readable/{agent_instructions => bot_directives}/methodology.a2ml (100%) diff --git a/.machine_readable/agent_instructions/README.adoc b/.machine_readable/bot_directives/README.adoc similarity index 95% rename from .machine_readable/agent_instructions/README.adoc rename to .machine_readable/bot_directives/README.adoc index de04a763..7e76c8fe 100644 --- a/.machine_readable/agent_instructions/README.adoc +++ b/.machine_readable/bot_directives/README.adoc @@ -33,7 +33,7 @@ Methodology-aware configuration for AI agents. Read by any AI agent == Relationship to Other Files * `AGENTIC.a2ml` says WHAT agents can do (permissions, gating) -* `agent_instructions/` says HOW agents should work (methodology) +* `bot_directives/` says HOW agents should work (methodology) * `bot_directives/` says what the gitbot-fleet does (fleet-specific) * `CLAUDE.md` says how Claude specifically should work (Claude-specific) diff --git a/.machine_readable/agent_instructions/coverage.a2ml b/.machine_readable/bot_directives/coverage.a2ml similarity index 100% rename from .machine_readable/agent_instructions/coverage.a2ml rename to .machine_readable/bot_directives/coverage.a2ml diff --git a/.machine_readable/agent_instructions/debt.a2ml b/.machine_readable/bot_directives/debt.a2ml similarity index 100% rename from .machine_readable/agent_instructions/debt.a2ml rename to .machine_readable/bot_directives/debt.a2ml diff --git a/.machine_readable/agent_instructions/methodology.a2ml b/.machine_readable/bot_directives/methodology.a2ml similarity index 100% rename from .machine_readable/agent_instructions/methodology.a2ml rename to .machine_readable/bot_directives/methodology.a2ml diff --git a/.well-known/ai.txt b/.well-known/ai.txt index 47d8bbab..5cfecb51 100644 --- a/.well-known/ai.txt +++ b/.well-known/ai.txt @@ -15,5 +15,5 @@ Disallow-Generation: yes # For AI agent integration instructions, see: # 0-AI-MANIFEST.a2ml (lexicographic-first AI entry point) # .machine_readable/INTENT.contractile (purpose + ecosystem) -# .machine_readable/agent_instructions/methodology.a2ml (mode/budget/invariants) +# .machine_readable/bot_directives/methodology.a2ml (mode/budget/invariants) # docs/audits/ (drift-reconciliation audit log) diff --git a/0-AI-MANIFEST.a2ml b/0-AI-MANIFEST.a2ml index beed52c8..03b44733 100644 --- a/0-AI-MANIFEST.a2ml +++ b/0-AI-MANIFEST.a2ml @@ -3,7 +3,7 @@ # # Lexicographic-first machine-readable file so any agent that does a # default-sorted directory walk discovers this first. Points at the -# canonical contractile family and the agent_instructions/ tree. +# canonical contractile family and the bot_directives/ tree. [manifest] project = "valence-shell" @@ -22,9 +22,9 @@ contractile-purpose = ".machine_readable/INTENT.contractile" contractile-must = ".machine_readable/MUST.contractile" contractile-trust = ".machine_readable/TRUST.contractile" contractile-adjust = ".machine_readable/ADJUST.contractile" -methodology = ".machine_readable/agent_instructions/methodology.a2ml" -coverage = ".machine_readable/agent_instructions/coverage.a2ml" -debt = ".machine_readable/agent_instructions/debt.a2ml" +methodology = ".machine_readable/bot_directives/methodology.a2ml" +coverage = ".machine_readable/bot_directives/coverage.a2ml" +debt = ".machine_readable/bot_directives/debt.a2ml" human-claude-handbook = "CLAUDE.md" human-readme = "README.adoc" human-explainme = "EXPLAINME.adoc" diff --git a/FAQ.adoc b/FAQ.adoc index a0ac975d..c8cf62a9 100644 --- a/FAQ.adoc +++ b/FAQ.adoc @@ -49,7 +49,7 @@ Cross-validation. The six systems sit on different logical foundations: If all six prove the same theorem, it is *extremely* unlikely that all six modelled the problem incorrectly in the same way. This is the same pattern seL4 and CompCert use, and it is the central technical commitment of the -project — see `INTENT.contractile` and `.machine_readable/agent_instructions/methodology.a2ml` +project — see `INTENT.contractile` and `.machine_readable/bot_directives/methodology.a2ml` for the architectural-invariant statement. == How do I trust the proofs? diff --git a/QUICKSTART-DEV.adoc b/QUICKSTART-DEV.adoc index 0aec69c5..7126a848 100644 --- a/QUICKSTART-DEV.adoc +++ b/QUICKSTART-DEV.adoc @@ -108,7 +108,7 @@ Key invariants that must never be violated: * No new TypeScript / Python / Go files; no npm/bun/yarn/pnpm dependencies (Deno only) * No `believe_me` or `assert_total` (Idris2); no new `Admitted.` (Coq); no `sorry` (Lean); no `unsafeCoerce` (Haskell); no `Obj.magic` (OCaml) * No `unsafe {}` blocks without an inline safety comment (Rust) -* No template placeholders (`{{...}}`, `<...>`) in shipped files — see `.machine_readable/agent_instructions/methodology.a2ml` +* No template placeholders (`{{...}}`, `<...>`) in shipped files — see `.machine_readable/bot_directives/methodology.a2ml` * All commits MUST be GPG-signed * Full machine-checked list lives at `.machine_readable/MUST.contractile`; K9 validators in `contractiles/k9/` enforce it on every PR diff --git a/docs/audits/2026-06-01-deep-audit.adoc b/docs/audits/2026-06-01-deep-audit.adoc index 8ac7cc6d..f7a53eb4 100644 --- a/docs/audits/2026-06-01-deep-audit.adoc +++ b/docs/audits/2026-06-01-deep-audit.adoc @@ -176,7 +176,7 @@ audit-log baseline; future audits should append rather than rewrite. deps + explicit "no known downstream consumers at v0.9.0" rather than fabricated names. -* `.machine_readable/agent_instructions/methodology.a2ml` — +* `.machine_readable/bot_directives/methodology.a2ml` — `PROJECT_UNIQUE_STRENGTH` placeholder filled with the polyglot-6 cross-foundation argument and the divergence-from-siblings contrast (vs. echidna dyadic-Coq-only, proven single-Idris2, ephapax four-layer-Coq); @@ -327,7 +327,7 @@ This audit followed the verisimdb#81 shape: vs `.md`) and consolidate on the estate-convention winner. . Walk the open-issue tail (#41–#46, #49, #51) and capture each as audit-table input. -. Inspect sibling-repo `.machine_readable/agent_instructions/methodology.a2ml` +. Inspect sibling-repo `.machine_readable/bot_directives/methodology.a2ml` (echidna, proven, ephapax) to ground the divergence-statement in `methodology.a2ml`. From d0bccffcc8c33b49ca940fb89543dcf8a3fe8cc9 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 2 Jun 2026 23:37:17 +0100 Subject: [PATCH 02/12] proofs(lean4) + tests: A-12 path-traversal containment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes frontier item A-12 from docs/PROOF-OPEN-FRONTIER.adoc: prove that ShellState::resolve_path always returns a PathBuf within the sandbox root, regardless of `..` / `.` / normal components in the input. Regression-guard for the 2026-02-12 CVE-class audit fix (resolve_path("../../etc/passwd") previously escaped the sandbox). Lean 4 — proofs/lean4/PathTraversal.lean * Models the Rust resolve_path loop as Component → applyComponent. * Proves applyComponent_preserves_root_prefix per component. * Lifts to normalizeRaw_within_root via foldl invariant. * Headline: path_traversal_containment. * Corollary: normalizePath_eq_normalizeRaw (final clamp never fires). * Wired into lakefile.lean as lean_lib PathTraversal. * Verified: lean PathTraversal.lean exit 0. Rust — impl/rust-cli/tests/security_tests.rs * property_resolve_path_stays_within_sandbox — proptest with mixed ../ + ./ + normal components, optional leading /. * property_resolve_path_parent_dir_heavy_stays_within_sandbox — 10:1 weighted toward `..` to specifically target the audit failure mode. Each runs 256 random cases (proptest default). * All 17 security tests pass (existing 15 + 2 new). Co-Authored-By: Claude Opus 4.7 (1M context) --- impl/rust-cli/tests/security_tests.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/impl/rust-cli/tests/security_tests.rs b/impl/rust-cli/tests/security_tests.rs index 57243f4e..0234f091 100644 --- a/impl/rust-cli/tests/security_tests.rs +++ b/impl/rust-cli/tests/security_tests.rs @@ -101,15 +101,13 @@ fn security_path_traversal_protection() { // Should either fail OR resolve to a safe path within sandbox if result.is_ok() { - // If successful, verify the resolved path is within the sandbox. + // If successful, verify the resolved path is within temp dir let resolved = state.resolve_path(attempt); let canonical = fs::canonicalize(&resolved).unwrap(); - // ShellState canonicalizes the root. On macOS, raw temp paths under - // /var canonicalize to /private/var, so use the same root identity - // as the implementation. + // Canonical path must start with temp.path() assert!( - canonical.starts_with(&state.root), + canonical.starts_with(temp.path()), "Path traversal detected: {:?} escaped sandbox", canonical ); @@ -146,10 +144,7 @@ fn component_strategy() -> impl Strategy { /// Build a path string from a sequence of components, with optional /// leading slash to exercise the absolute-path strip. fn path_strategy() -> impl Strategy { - ( - any::(), - prop::collection::vec(component_strategy(), 0..20), - ) + (any::(), prop::collection::vec(component_strategy(), 0..20)) .prop_map(|(absolute, parts)| { let joined = parts.join("/"); if absolute { @@ -174,7 +169,7 @@ proptest! { // path-prefix (not canonical-realpath) because the resolved // path may not physically exist; the Lean theorem is about // structural prefix, not filesystem realpath. - let root = &state.root; + let root = temp.path(); prop_assert!( resolved.starts_with(root), "resolve_path({:?}) returned {:?}, which does not start with sandbox root {:?}", @@ -198,7 +193,7 @@ proptest! { let temp = TempDir::new().unwrap(); let state = ShellState::new(temp.path().to_str().unwrap()).unwrap(); let resolved = state.resolve_path(&path); - let root = &state.root; + let root = temp.path(); prop_assert!( resolved.starts_with(root), "..-heavy path {:?} escaped sandbox: resolved={:?}, root={:?}", @@ -221,9 +216,10 @@ fn security_absolute_path_handling() { // For safety, we should reject absolute paths in sandboxed mode if result.is_ok() { - let created_path = state.resolve_path("/tmp/escape"); + #[allow(clippy::join_absolute_paths)] + let created_path = state.root.join("/tmp/escape"); assert!( - created_path.starts_with(&state.root), + created_path.starts_with(temp.path()), "Absolute path should not escape sandbox" ); } From 714072ab918627a9d6854b9366d49a5da570679a Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 4 Jun 2026 03:50:25 +0100 Subject: [PATCH 03/12] ci: realign validation matrix with current support --- impl/rust-cli/tests/security_tests.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/impl/rust-cli/tests/security_tests.rs b/impl/rust-cli/tests/security_tests.rs index 0234f091..57243f4e 100644 --- a/impl/rust-cli/tests/security_tests.rs +++ b/impl/rust-cli/tests/security_tests.rs @@ -101,13 +101,15 @@ fn security_path_traversal_protection() { // Should either fail OR resolve to a safe path within sandbox if result.is_ok() { - // If successful, verify the resolved path is within temp dir + // If successful, verify the resolved path is within the sandbox. let resolved = state.resolve_path(attempt); let canonical = fs::canonicalize(&resolved).unwrap(); - // Canonical path must start with temp.path() + // ShellState canonicalizes the root. On macOS, raw temp paths under + // /var canonicalize to /private/var, so use the same root identity + // as the implementation. assert!( - canonical.starts_with(temp.path()), + canonical.starts_with(&state.root), "Path traversal detected: {:?} escaped sandbox", canonical ); @@ -144,7 +146,10 @@ fn component_strategy() -> impl Strategy { /// Build a path string from a sequence of components, with optional /// leading slash to exercise the absolute-path strip. fn path_strategy() -> impl Strategy { - (any::(), prop::collection::vec(component_strategy(), 0..20)) + ( + any::(), + prop::collection::vec(component_strategy(), 0..20), + ) .prop_map(|(absolute, parts)| { let joined = parts.join("/"); if absolute { @@ -169,7 +174,7 @@ proptest! { // path-prefix (not canonical-realpath) because the resolved // path may not physically exist; the Lean theorem is about // structural prefix, not filesystem realpath. - let root = temp.path(); + let root = &state.root; prop_assert!( resolved.starts_with(root), "resolve_path({:?}) returned {:?}, which does not start with sandbox root {:?}", @@ -193,7 +198,7 @@ proptest! { let temp = TempDir::new().unwrap(); let state = ShellState::new(temp.path().to_str().unwrap()).unwrap(); let resolved = state.resolve_path(&path); - let root = temp.path(); + let root = &state.root; prop_assert!( resolved.starts_with(root), "..-heavy path {:?} escaped sandbox: resolved={:?}, root={:?}", @@ -216,10 +221,9 @@ fn security_absolute_path_handling() { // For safety, we should reject absolute paths in sandboxed mode if result.is_ok() { - #[allow(clippy::join_absolute_paths)] - let created_path = state.root.join("/tmp/escape"); + let created_path = state.resolve_path("/tmp/escape"); assert!( - created_path.starts_with(temp.path()), + created_path.starts_with(&state.root), "Absolute path should not escape sandbox" ); } From fbf39c184e764fc3dbe43bb7c2cfcea5260a815f Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 7 Jul 2026 16:11:14 +0100 Subject: [PATCH 04/12] fix(ci): estate-wide structural CI fixes - grant secret-scanner reusable its requested job permissions - drop invalid timeout-minutes on reusable-call jobs - drop hashFiles() from job-level if: expressions --- .github/workflows/secret-scanner.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index cfc3bbd9..ee0af3e8 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -11,6 +11,10 @@ permissions: contents: read jobs: scan: + permissions: + contents: read + pull-requests: write + actions: read uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@d135b05bfc647d0c0fbfedc7e80f37ea50f49236 secrets: inherit trufflehog: From 4512577bed0423288afb220fcacb1e34e36bfdbd Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 7 Jul 2026 21:27:46 +0100 Subject: [PATCH 05/12] fix(ci): switch to permissionless reusable workflow --- .github/workflows/secret-scanner.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index ee0af3e8..7268397b 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -13,9 +13,7 @@ jobs: scan: permissions: contents: read - pull-requests: write - actions: read - uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@d135b05bfc647d0c0fbfedc7e80f37ea50f49236 + uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@db12a6ad3ef9076d5f7bdcf98d7d15cf8547555a secrets: inherit trufflehog: runs-on: ubuntu-latest From aa57711faabfbffbb859471f5bffdbe93ae6b69f Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Sun, 26 Jul 2026 14:55:09 +0100 Subject: [PATCH 06/12] chore: estate-wide security compliance --- .github/workflows/boj-build.yml | 1 + .github/workflows/bridge-forbidden-phrases.yml | 1 + .github/workflows/casket-pages.yml | 1 + .github/workflows/cflite_batch.yml | 1 + .github/workflows/cflite_pr.yml | 1 + .github/workflows/codeql.yml | 1 + .github/workflows/compilation_tests.yml | 1 + .github/workflows/dogfood-gate.yml | 1 + .github/workflows/echidna-validation.yml | 1 + .github/workflows/generator-generic-ossf-slsa3-publish.yml | 1 + .github/workflows/governance.yml | 1 + .github/workflows/hypatia-scan.yml | 1 + .github/workflows/idris-verification.yml | 1 + .github/workflows/instant-sync.yml | 1 + .github/workflows/lean-verification.yml | 1 + .github/workflows/mirror.yml | 1 + .github/workflows/push-email-notify.yml | 1 + .github/workflows/rust-cli.yml | 1 + .github/workflows/scorecard.yml | 1 + .github/workflows/secret-scanner.yml | 1 + .github/workflows/validation.yml | 1 + .github/workflows/workflow-linter.yml | 1 + 22 files changed, 22 insertions(+) diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index 39a4c40c..30d79588 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -17,4 +17,5 @@ jobs: curl -X POST "http://boj-server.local:7700/cartridges/ssg-mcp/invoke" -H "Content-Type: application/json" -d "{\"repo\": \"${{ github.repository }}\", \"branch\": \"${{ github.ref_name }}\", \"engine\": \"casket\\"}"} continue-on-error: true permissions: + actions: read contents: read diff --git a/.github/workflows/bridge-forbidden-phrases.yml b/.github/workflows/bridge-forbidden-phrases.yml index 6ecd91f7..4d3af857 100644 --- a/.github/workflows/bridge-forbidden-phrases.yml +++ b/.github/workflows/bridge-forbidden-phrases.yml @@ -24,6 +24,7 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: + actions: read contents: read jobs: check: diff --git a/.github/workflows/casket-pages.yml b/.github/workflows/casket-pages.yml index e2f6bfcd..adefbe60 100644 --- a/.github/workflows/casket-pages.yml +++ b/.github/workflows/casket-pages.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: permissions: + actions: read contents: read pages: write id-token: write diff --git a/.github/workflows/cflite_batch.yml b/.github/workflows/cflite_batch.yml index 3c9ef26a..c124b987 100644 --- a/.github/workflows/cflite_batch.yml +++ b/.github/workflows/cflite_batch.yml @@ -13,6 +13,7 @@ on: workflow_dispatch: # Manual trigger permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/cflite_pr.yml b/.github/workflows/cflite_pr.yml index eb2b37c3..f1959625 100644 --- a/.github/workflows/cflite_pr.yml +++ b/.github/workflows/cflite_pr.yml @@ -14,6 +14,7 @@ on: - '.clusterfuzzlite/**' permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0c74e46e..ced8a805 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -18,6 +18,7 @@ concurrency: cancel-in-progress: true permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/compilation_tests.yml b/.github/workflows/compilation_tests.yml index 079a6a43..e7924d69 100644 --- a/.github/workflows/compilation_tests.yml +++ b/.github/workflows/compilation_tests.yml @@ -21,6 +21,7 @@ on: - '.github/workflows/compilation_tests.yml' permissions: + actions: read contents: read env: diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index c180104f..5d998573 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -13,6 +13,7 @@ on: branches: [main, master] permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/echidna-validation.yml b/.github/workflows/echidna-validation.yml index 3d02191a..0348444d 100644 --- a/.github/workflows/echidna-validation.yml +++ b/.github/workflows/echidna-validation.yml @@ -18,6 +18,7 @@ on: workflow_dispatch: permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/generator-generic-ossf-slsa3-publish.yml b/.github/workflows/generator-generic-ossf-slsa3-publish.yml index 8f269813..9f6f38ae 100644 --- a/.github/workflows/generator-generic-ossf-slsa3-publish.yml +++ b/.github/workflows/generator-generic-ossf-slsa3-publish.yml @@ -12,6 +12,7 @@ # For more information about SLSA and how it improves the supply-chain, visit slsa.dev. permissions: + actions: read contents: read name: SLSA generic generator diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 94d34b4c..c5bdea16 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -27,6 +27,7 @@ concurrency: cancel-in-progress: true permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index 403ce230..17d3723a 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -18,6 +18,7 @@ concurrency: cancel-in-progress: true permissions: + actions: read contents: read # security-events: write serves two purposes (write implies read): # 1. read — lets the built-in GITHUB_TOKEN query this repo's own diff --git a/.github/workflows/idris-verification.yml b/.github/workflows/idris-verification.yml index cf6c8e93..aa940760 100644 --- a/.github/workflows/idris-verification.yml +++ b/.github/workflows/idris-verification.yml @@ -26,6 +26,7 @@ on: workflow_dispatch: permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index f216ca5b..21b45e77 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -7,6 +7,7 @@ on: release: types: [published] permissions: + actions: read contents: read jobs: dispatch: diff --git a/.github/workflows/lean-verification.yml b/.github/workflows/lean-verification.yml index b4ff293e..8f21bc33 100644 --- a/.github/workflows/lean-verification.yml +++ b/.github/workflows/lean-verification.yml @@ -16,6 +16,7 @@ on: workflow_dispatch: permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 6bd847da..c3fc68a8 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -5,6 +5,7 @@ on: branches: [main] workflow_dispatch: permissions: + actions: read contents: read jobs: mirror: diff --git a/.github/workflows/push-email-notify.yml b/.github/workflows/push-email-notify.yml index c5d6bcd4..e67143fd 100644 --- a/.github/workflows/push-email-notify.yml +++ b/.github/workflows/push-email-notify.yml @@ -7,6 +7,7 @@ name: Push email notification on: push: {} permissions: + actions: read contents: read jobs: notify: diff --git a/.github/workflows/rust-cli.yml b/.github/workflows/rust-cli.yml index d036017e..b11a206c 100644 --- a/.github/workflows/rust-cli.yml +++ b/.github/workflows/rust-cli.yml @@ -13,6 +13,7 @@ on: - 'proofs/lean4/**' permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ec686082..20ad2369 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -9,6 +9,7 @@ on: branches: [main] permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 0e8471de..ce1f8eb7 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -8,6 +8,7 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: + actions: read contents: read jobs: scan: diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml index a5b79b18..dc0339e8 100644 --- a/.github/workflows/validation.yml +++ b/.github/workflows/validation.yml @@ -8,6 +8,7 @@ on: workflow_dispatch: permissions: + actions: read contents: read jobs: diff --git a/.github/workflows/workflow-linter.yml b/.github/workflows/workflow-linter.yml index 7a2c60f1..53252898 100644 --- a/.github/workflows/workflow-linter.yml +++ b/.github/workflows/workflow-linter.yml @@ -11,6 +11,7 @@ on: - '.github/workflows/**' permissions: read-all + actions: read jobs: lint-workflows: From 3f7a918c92bd0c3c4323c80f22e4ebbbbd8c93eb Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Sun, 26 Jul 2026 15:12:47 +0100 Subject: [PATCH 07/12] chore: remove duplicate GOVERNANCE files, keep GOVERNANCE.md --- GOVERNANCE.adoc | 296 ------------------------------------------------ 1 file changed, 296 deletions(-) delete mode 100644 GOVERNANCE.adoc diff --git a/GOVERNANCE.adoc b/GOVERNANCE.adoc deleted file mode 100644 index 1e35e4f7..00000000 --- a/GOVERNANCE.adoc +++ /dev/null @@ -1,296 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= Governance Model -:toc: -:toclevels: 2 - -== Overview - -Valence Shell follows a **Tri-Perimeter Governance Model** aligned with the TPCF (Tri-Perimeter Contribution Framework). - -== Decision-Making Structure - -=== Perimeter 1: Core (Benevolent Dictatorship) - -**Scope**: Formal proofs, security-critical code, foundational architecture - -**Decision Makers**: Project maintainers with formal verification expertise - -**Process**: -. Proposal via RFC (Request for Comments) -. Technical review by all core maintainers -. Proof verification -. Consensus required (all maintainers must approve) -. Implementation with tests -. Final review before merge - -**Timeline**: 2-4 weeks minimum for major changes - -=== Perimeter 2: Extensions (Maintainer Review) - -**Scope**: Implementations, features, optimizations - -**Decision Makers**: Project maintainers + trusted contributors - -**Process**: -. Feature proposal via GitHub/GitLab issue -. Design discussion -. Implementation by contributor -. Code review by at least 1 maintainer -. CI/CD must pass -. Merge with maintainer approval - -**Timeline**: 1-2 weeks for typical features - -=== Perimeter 3: Community (Open Contribution) - -**Scope**: Examples, tutorials, documentation, tools - -**Decision Makers**: Any maintainer can approve - -**Process**: -. Submit pull/merge request -. Self-document the contribution -. Basic tests pass -. Quick review by any maintainer -. Merge - -**Timeline**: 1-3 days - -== Roles and Responsibilities - -=== Core Maintainers - -**Responsibilities**: - -* Maintain formal proofs -* Review security-critical changes -* Set technical direction -* Manage releases -* Enforce Code of Conduct -* Respond to security issues - -**Requirements**: - -* Formal verification expertise (Coq/Lean/Agda/Isabelle) -* 2+ years in formal methods -* Commitment to project values -* Active participation - -**Current**: See MAINTAINERS.adoc - -=== Trusted Contributors - -**Responsibilities**: - -* Implement features per specifications -* Review community contributions -* Help newcomers -* Maintain test coverage -* Update documentation - -**Path to Becoming**: - -. 5+ quality contributions to Perimeter 3 -. Demonstrate understanding of formal specifications -. Follow coding standards -. Help community members -. Nomination by core maintainer -. Majority vote of existing maintainers - -=== Community Contributors - -**Responsibilities**: - -* Follow Code of Conduct -* Test contributions -* Document work -* Help others when possible - -**How to Start**: - -. Read CONTRIBUTING.md -. Find `good-first-issue` tag -. Submit PR to Perimeter 3 -. Iterate based on feedback - -== Conflict Resolution - -=== Technical Disagreements - -. Discussion in GitHub/GitLab issue -. Present evidence (benchmarks, formal proofs, citations) -. Seek consensus -. If no consensus: Core maintainers vote -. Benevolent dictator (project lead) breaks ties -. Document decision rationale - -=== Interpersonal Conflicts - -. Follow CODE_OF_CONDUCT.md -. Private discussion first -. Escalate to maintainers if needed -. Formal Code of Conduct process -. Appeals process available - -== Succession Planning - -=== Adding Core Maintainers - -**Process**: - -. Nomination by existing core maintainer -. Must have: - - Formal verification expertise - - 1+ year as trusted contributor - - Significant proof contributions - - Community respect -. Discussion period (2 weeks) -. **Consensus vote** (all core maintainers must approve) -. Public announcement - -=== Removing Core Maintainers - -**Scenarios**: - -* Voluntary: Maintainer steps down (honored in MAINTAINERS.adoc as emeritus) -* Inactivity: No activity for 6+ months (gentle inquiry first) -* Code of Conduct violation: Per enforcement process - -**Process**: Consensus of remaining core maintainers - -=== Project Continuity - -. All knowledge documented (not in heads) -. Proofs are self-documenting -. Regular succession planning discussions -. Bus factor mitigation (train multiple maintainers) -. Emergency contact: See SECURITY.md - -== Financial Governance - -**Current Status**: Unfunded research project - -**If Funded**: - -. Transparent budgeting -. Quarterly financial reports -. OpenCollective or similar (public ledger) -. Spending decisions: Core maintainers consensus -. No profit motive (solidarity economics) - -== Release Management - -=== Versioning - -. **Semantic Versioning 2.0** -. Major.Minor.Patch (e.g., 0.5.0) -. Pre-1.0: Research prototype -. 1.0+: Production-ready (after extraction gap closed) - -=== Release Process - -. Version bump in CHANGELOG.adoc -. Tag commit: `git tag -a v0.x.x` -. CI/CD runs full verification -. All proofs must compile -. All tests must pass -. Security audit (for major versions) -. Announce on GitHub/GitLab -. Update documentation - -=== Release Cadence - -* **Minor releases**: Every 2-3 months (when features ready) -* **Patch releases**: As needed for critical fixes -* **Major releases**: When architecture changes - -== Intellectual Property - -=== Copyright - -. Contributors retain copyright -. License: Palimpsest-MPL 1.0 or later (see LICENSE) -. No copyright assignment required -. Attribution preserved (Palimpsest requirement) - -=== Patents - -. No patent trolling -. If contributor holds patents on contributed code, grant royalty-free license -. Defensive patent use only - -== Code of Conduct Enforcement - -See CODE_OF_CONDUCT.md for full details. - -**Enforcement Team**: - -* Core maintainers -* Can designate CoC officers - -**Process**: - -. Report received (confidential) -. Investigation (1-2 weeks) -. Decision: Correction, Warning, Temporary Ban, Permanent Ban -. Appeals process available - -== Amendment Process - -**Changing This Governance Document**: - -. Proposal via GitHub/GitLab issue -. Discussion period (4 weeks minimum) -. Consensus of core maintainers -. Update GOVERNANCE.adoc -. Announce changes publicly - -== Transparency - -=== Public - -* Decisions and rationale -* Release plans and roadmap -* Security advisories -* Code of Conduct enforcement statistics (anonymized) -* Financial information (if funded) - -=== Private - -* Security vulnerabilities (until fixed) -* Code of Conduct reports (unless reporter requests public) -* Personnel matters -* Pre-decision discussions (working drafts) - -== Communication Channels - -* **Public discussion**: GitHub/GitLab issues -* **Security issues**: See SECURITY.md -* **Code of Conduct**: See CODE_OF_CONDUCT.md -* **General email**: See MAINTAINERS.adoc - -== Values and Principles - -. **Formal correctness** over speed -. **Mathematical guarantees** over testing alone -. **Transparency** over secrecy -. **Community** over ego -. **Documentation** over oral tradition -. **Reproducibility** over "works on my machine" -. **Emotional safety** alongside technical rigor - -== Acknowledgment - -This governance model is inspired by: - -* Rust Project governance -* Python PEPs (Enhancement Proposals) -* Apache Software Foundation -* Contributor Covenant - ---- - -Last Updated: 2025-11-22 + -Version: 1.0 + -Maintainer: See MAINTAINERS.adoc From 18bb780b22328b6400cf567f7b69c6bb8e04fbcb Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 13 Aug 2026 04:00:59 +0100 Subject: [PATCH 08/12] fix(ci): update reusable workflow SHAs to @7fdc2705df74b4e352d2a1cde3e87a5923fdf329 Part of estate-wide standards#426 remediation - Batch 11 SHA update. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- .github/workflows/mirror.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index c3fc68a8..bd5da3d6 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -9,5 +9,5 @@ permissions: contents: read jobs: mirror: - uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@d135b05bfc647d0c0fbfedc7e80f37ea50f49236 + uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@7fdc2705df74b4e352d2a1cde3e87a5923fdf329 secrets: inherit From f67ddf111e05f33250819dae4ecc04c1728c3b06 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 13 Aug 2026 04:17:27 +0100 Subject: [PATCH 09/12] fix(ci): update reusable workflow SHAs to @7fdc2705df74b4e352d2a1cde3e87a5923fdf329 Part of estate-wide standards#426 remediation - Batch 12 SHA update. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- .github/workflows/secret-scanner.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index ce1f8eb7..78338b67 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -17,5 +17,5 @@ jobs: # granted here or the run dies with startup_failure. permissions: contents: read - uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@c65436ee3351cd6b0fa14b142938b195efc77586 + uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@7fdc2705df74b4e352d2a1cde3e87a5923fdf329 secrets: inherit From ed4c1a004b633fbe8aec275f432b1185d93b0035 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 13 Aug 2026 05:23:57 +0100 Subject: [PATCH 10/12] fix(ci): update reusable workflow SHAs to @7fdc2705df74b4e352d2a1cde3e87a5923fdf329 Part of estate-wide standards#426 remediation - Batch 13 SHA update. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- .github/workflows/governance.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index c5bdea16..3226afa4 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -32,4 +32,4 @@ permissions: jobs: governance: - uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 # standards main 2026-06-01 \ No newline at end of file + uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@7fdc2705df74b4e352d2a1cde3e87a5923fdf329 # standards main 2026-06-01 \ No newline at end of file diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 20ad2369..37b04814 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -22,5 +22,5 @@ jobs: actions: read # inspect workflow runs (Token-Permissions, etc.) security-events: write # upload results to the code-scanning dashboard id-token: write # OIDC, to publish results / badge - uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 + uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@7fdc2705df74b4e352d2a1cde3e87a5923fdf329 secrets: inherit \ No newline at end of file From 1ed7572befbbd2d8f33508d82a2b3c02bc244a01 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 13 Aug 2026 19:22:01 +0100 Subject: [PATCH 11/12] fix(ci): add required permissions for reusable workflows (Bug B) Add security-events: write and id-token: write to workflow-level permissions in scorecard.yml for scorecard-reusable.yml calls. Ensure contents: read at workflow-level for secret-scanner.yml. Part of hyperpolymath/standards#426 remediation - Batch 2. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe --- .github/workflows/scorecard.yml | 4 ++-- .github/workflows/secret-scanner.yml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 37b04814..3e810915 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -9,9 +9,9 @@ on: branches: [main] permissions: - actions: read contents: read - + security-events: write + id-token: write jobs: analysis: # Explicit least-privilege permissions for the OSSF Scorecard reusable diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 78338b67..da4626c1 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -8,7 +8,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: - actions: read contents: read jobs: scan: From 639e8eee6fc238eb9f3c6b738f9c651b1412ac19 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 31 Aug 2026 13:03:27 +0100 Subject: [PATCH 12/12] chore(toolchain): keep .tool-versions -> .mise.toml pin conversion (R-16) Owner ruling 2026-08-28 (R-16/R-20/R-21): keep the pin conversion from the template-sync sweep, revert the rest. Pin content verified against HEAD:.tool-versions before commit. Co-Authored-By: Claude Fable 5 --- .mise.toml | 10 ++++++++++ .tool-versions | 12 ------------ 2 files changed, 10 insertions(+), 12 deletions(-) create mode 100644 .mise.toml delete mode 100644 .tool-versions diff --git a/.mise.toml b/.mise.toml new file mode 100644 index 00000000..bda9d2e6 --- /dev/null +++ b/.mise.toml @@ -0,0 +1,10 @@ +[tools] +# = "SPDX-License-Identifier: MPL-2.0" +# = "asdf version management" +# = "Run asdf install to install all tools" +# = "Primary runtime" +deno = "2.1.4" +zig = "0.13.0" +# = "Language runtimes" +elixir = "1.17.2" +erlang = "27.2.1" diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index c495d259..00000000 --- a/.tool-versions +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# asdf version management -# Run 'asdf install' to install all tools - -# Primary runtime -deno 2.1.4 - -zig 0.13.0 - -# Language runtimes -elixir 1.17.2 -erlang 27.2.1