Add ManifestMeta to manifest loader for signature validation:
- load_manifest_with_meta() rejects unsigned manifests when
signatures_required=true and signature_valid=false
- Clear error message directs operator to quorum administrator
- Backward compatible: load_manifest() passes default meta (no check)
2 new tests for signature rejection and acceptance.
Signed-off-by: Tyler King <tking@guildhouse.dev>
Signed-off-by: Tyler J King <tking727@gmail.com>
Add 'gsh corpus' org-ops module with install/list/verify/remove
subcommands. Orchestrates existing package managers and wraps each
installation with Corpus attestation:
- Resolves package source (apt, dnf, direct, auto-stub)
- Downloads via existing package manager
- Computes CID (SHA-256) and generates SBOM (syft or SPDX stub)
- Infers ShellGovernance (shell class, tier, delegation context)
from known binary classifications
- Creates CorpusEntry CRD via kubectl apply
- Places binary in governed path (/governed/app/bin or system/bin)
corpus verify: checks on-disk binary hashes against manifest CIDs
corpus list: kubectl get corpusentries
corpus remove: kubectl delete corpusentry
8 unit tests for inference logic and SBOM generation.
Signed-off-by: Tyler King <tking@guildhouse.dev>
Signed-off-by: Tyler J King <tking727@gmail.com>
Move all BXNet-specific defaults out of org-ops-core into the example
CLI binary (org-ops-cli/src/main.rs). The framework is now fork-ready
for any consortium without string-replacing org-specific values.
Changes:
- OrgOpsConfig: neutral defaults (my-org, example.com), added
infra_namespace, bridge_daemonset, ssh_user fields
- AuthConfig: config_dir_name field replaces hardcoded bxnet-ops
path; config_dir() now a method using config value
- GitConfig: neutral default (git.example.com)
- auth_commands: DID_BRIDGE_PATH env replaces hardcoded dev path
- lib.rs (connect): namespace, daemonset, SSH user, cert paths all
read from OrgOpsConfig instead of hardcoded strings
- score_fetcher: neutral corpus entry name
- playbook_commands: neutral Keycloak service name and temp dir
- org-ops-cli/main.rs: explicit BXNet example with "replace these"
comment, all org-specific values passed via config
- .gitignore: added target/
Zero BXNet references remain in org-ops-core source (verified by grep).
Signed-off-by: Tyler King <tking@guildhouse.dev>
Signed-off-by: Tyler J King <tking727@gmail.com>
Add worker_preflight() check at dispatch time for commands that
target remote hosts. Enforces three conditions:
1. Session has delegation authority
2. Target host is in delegation scope
3. Target host posture satisfies required shell class
OrgCommands trait extended with target_host() method (default: None
for local commands). SessionContext enriched with delegation_scope.
Lightweight DelegationScope duplicate avoids bascule-core dep chain.
Target posture reader stubbed — requires gateway posture query API
(tracked as follow-up).
Fail-closed: unknown delegation -> denied, unknown posture -> denied.
11 unit tests for delegation and preflight.
Signed-off-by: Tyler King <tking@guildhouse.dev>
Signed-off-by: Tyler J King <tking727@gmail.com>
Add required_shell_class() to OrgCommands trait with Application
default (backward compatible). GSH dispatch checks session ShellClass
against command requirement before execution.
- ShellClass enum (local, lightweight — avoids bascule-core dep)
- SessionContext enriched with shell_class and posture_level
- Clear error on insufficient shell class directs operator to
reconnect via attested host for System access
- All existing commands work unchanged (Application default)
Signed-off-by: Tyler King <tking@guildhouse.dev>
Signed-off-by: Tyler J King <tking727@gmail.com>
Add emit_git_event() method to ChronicleClient that embeds a
GovernanceEnvelope in the CloudEvent data payload. The CloudEvent
id is set to the hex-encoded git_ref from the envelope.
Migrate GOV_COMMIT_CREATED, GOV_PUSH, and GOV_PR_CREATED in
git_commands.rs to use emit_git_event(). Non-git events continue
to use the existing emit() method.
Signed-off-by: Tyler King <tking@guildhouse.dev>
org-ops-core now re-exports git_blob_hash, git_blob_hash_hex, and
git_blob_cid from the shared governance-types crate. BPF key
helpers remain local. sha1 direct dependency removed (transitive
through governance-types).
Signed-off-by: Tyler King <tking@guildhouse.dev>
Add git_hash module that computes SHA-1 blob hashes identical to
`git hash-object --stdin`. Includes BPF map key extraction that
handles both legacy sha256: and new gitsha1: CID formats.
Migrate TestRunResult::compute_cid() from custom SHA-256 to git
blob hash. New CID format: `gitsha1:{40 hex chars}`. File storage
path uses the full CID as filename (backward compatible for reads
since old files retain their sha256: names).
New dependency: sha1 0.10 (RustCrypto, same family as sha2).
See cid-reconciliation-audit.md Sites 1, 3.
Signed-off-by: Tyler King <tking@guildhouse.dev>
Replace fake Forgejo push webhook for AI_RISK_ASSESSMENT with
structured CloudEvents 1.0. Event now carries confidence_score,
recommendation, test_results_analyzed, and diff_match as typed
fields instead of a flat message string.
Event rename: AI_RISK_ASSESSMENT -> GOV_AI_RISK_ASSESSMENT
Signed-off-by: Tyler King <tking@guildhouse.dev>
Replace fake Forgejo push webhook construction with structured
CloudEvents 1.0 via ChronicleClient. Git commit SHAs are now used
as CloudEvent ids for COMMIT_CREATED and PUSH events, enabling
direct correlation between Chronicle entries and git history.
Event renames:
- REPO_CLONED -> GOV_REPO_CLONED
- COMMIT_CREATED -> GOV_COMMIT_CREATED
- GOVERNED_PUSH -> GOV_PUSH
- PR_CREATED -> GOV_PR_CREATED
Signed-off-by: Tyler King <tking@guildhouse.dev>
The reasoning_cid was computed via SHA-256 but immediately discarded
(`let _ = reasoning_cid`). Remove the dead hash computation and the
now-unused sha2 import.
Ref: cid-reconciliation-audit.md Site 5
Signed-off-by: Tyler King <tking@guildhouse.dev>
The governed playbook runner now:
1. Requests an AC from the GSAP broker before execution
2. Validates corpus CID + parameters CID + single-use
3. Executes the ansible playbook (unchanged)
4. Posts a Completion Receipt to the broker after execution
Environment variables:
GSAP_BROKER_URL — Capstone broker endpoint
GSAP_BEARER_TOKEN — JWT for broker auth
GSAP_DRIVER_ID — identity driver (default: keycloak-guildhouse)
GSAP_ACCORD_TEMPLATE — accord template (default: from GUILDHOUSE_ACCORD)
GSAP_SESSION_DIR — local session state directory
Self-authorized mode:
If GSAP_BROKER_URL not set, execution proceeds without AC/CR.
Valid for development (GSAP §1.3). Not for production.
Error handling:
ElevationRequired → shows activation instructions, aborts
Denied → shows reason, aborts
CorpusMismatch → shows CID diff, aborts
CR delivery failure → stores locally, warns, does not abort
4/4 gsap_client unit tests passing.
Build clean with zero errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements the shell side of GCAP-SPEC-SHELLBOUND-BROKER-0001.
The broker (Capstone) issues ACs. This module consumes them.
GsapClient:
authorize() — request AC, validate R-20/R-22/R-23/R-24
complete() — post CR with 3x retry (R-29)
ConsumedContextRegistry:
Filesystem-based replay prevention (R-22)
4/4 unit tests passing:
test_corpus_mismatch, test_params_modified,
test_replay_rejected, test_valid_ac
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>