diff --git a/bin/disinto b/bin/disinto index 7a9482b..2e39c50 100755 --- a/bin/disinto +++ b/bin/disinto @@ -665,41 +665,6 @@ setup_forge() { _FORGE_ADMIN_PASS="$admin_pass" fi - # Create human user (johba) as site admin if it doesn't exist - local human_user="johba" - local human_pass - human_pass="human-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)" - - if ! curl -sf --max-time 5 "${forge_url}/api/v1/users/${human_user}" >/dev/null 2>&1; then - echo "Creating human user: ${human_user}" - local create_output - if ! create_output=$(_forgejo_exec forgejo admin user create \ - --admin \ - --username "${human_user}" \ - --password "${human_pass}" \ - --email "johba@disinto.local" \ - --must-change-password=false 2>&1); then - echo "Error: failed to create human user '${human_user}':" >&2 - echo " ${create_output}" >&2 - exit 1 - fi - # Forgejo 11.x ignores --must-change-password=false on create; - # explicitly clear the flag so basic-auth token creation works. - _forgejo_exec forgejo admin user change-password \ - --username "${human_user}" \ - --password "${human_pass}" \ - --must-change-password=false - - # Verify human user was actually created - if ! curl -sf --max-time 5 "${forge_url}/api/v1/users/${human_user}" >/dev/null 2>&1; then - echo "Error: human user '${human_user}' not found after creation" >&2 - exit 1 - fi - echo " Human user '${human_user}' created as site admin" - else - echo "Human user: ${human_user} (already exists)" - fi - # Get or create admin token local admin_token admin_token=$(curl -sf -X POST \ @@ -722,36 +687,6 @@ setup_forge() { exit 1 fi - # Get or create human user token - local human_token - if curl -sf --max-time 5 "${forge_url}/api/v1/users/${human_user}" >/dev/null 2>&1; then - human_token=$(curl -sf -X POST \ - -u "${human_user}:${human_pass}" \ - -H "Content-Type: application/json" \ - "${forge_url}/api/v1/users/${human_user}/tokens" \ - -d '{"name":"disinto-human-token","scopes":["all"]}' 2>/dev/null \ - | jq -r '.sha1 // empty') || human_token="" - - if [ -z "$human_token" ]; then - # Token might already exist — try listing - human_token=$(curl -sf \ - -u "${human_user}:${human_pass}" \ - "${forge_url}/api/v1/users/${human_user}/tokens" 2>/dev/null \ - | jq -r '.[0].sha1 // empty') || human_token="" - fi - - if [ -n "$human_token" ]; then - # Store human token in .env - if grep -q '^HUMAN_TOKEN=' "$env_file" 2>/dev/null; then - sed -i "s|^HUMAN_TOKEN=.*|HUMAN_TOKEN=${human_token}|" "$env_file" - else - printf 'HUMAN_TOKEN=%s\n' "$human_token" >> "$env_file" - fi - export HUMAN_TOKEN="$human_token" - echo " Human token saved (HUMAN_TOKEN)" - fi - fi - # Create bot users and tokens # Each agent gets its own Forgejo account for identity and audit trail (#747). # Map: bot-username -> env-var-name for the token @@ -768,7 +703,7 @@ setup_forge() { local env_file="${FACTORY_ROOT}/.env" local bot_user bot_pass token token_var - for bot_user in dev-bot review-bot planner-bot gardener-bot vault-bot supervisor-bot predictor-bot architect-bot; do + for bot_user in dev-bot review-bot planner-bot gardener-bot vault-bot supervisor-bot predictor-bot; do bot_pass="bot-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)" token_var="${bot_token_vars[$bot_user]}" @@ -870,50 +805,23 @@ setup_forge() { -H "Content-Type: application/json" \ "${forge_url}/api/v1/orgs/${org_name}/repos" \ -d "{\"name\":\"${repo_name}\",\"auto_init\":false,\"default_branch\":\"main\"}" >/dev/null 2>&1; then - # Fallback: create under the human user namespace (johba) + # Fallback: create under the dev-bot user curl -sf -X POST \ - -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ + -H "Authorization: token ${FORGE_TOKEN}" \ -H "Content-Type: application/json" \ - "${forge_url}/api/v1/users/${human_user}/repos" \ + "${forge_url}/api/v1/user/repos" \ -d "{\"name\":\"${repo_name}\",\"auto_init\":false,\"default_branch\":\"main\"}" >/dev/null 2>&1 || true fi - # Add all bot users as collaborators with appropriate permissions - # dev-bot: write (PR creation via lib/vault.sh) - # review-bot: read (PR review) - # planner-bot: write (prerequisites.md, memory) - # gardener-bot: write (backlog grooming) - # vault-bot: write (vault items) - # supervisor-bot: read (health monitoring) - # predictor-bot: read (pattern detection) - # architect-bot: write (sprint PRs) - local bot_user bot_perm - declare -A bot_permissions=( - [dev-bot]="write" - [review-bot]="read" - [planner-bot]="write" - [gardener-bot]="write" - [vault-bot]="write" - [supervisor-bot]="read" - [predictor-bot]="read" - [architect-bot]="write" - ) - for bot_user in "${!bot_permissions[@]}"; do - bot_perm="${bot_permissions[$bot_user]}" + # Add all bot users as collaborators + for bot_user in dev-bot review-bot planner-bot gardener-bot vault-bot supervisor-bot predictor-bot; do curl -sf -X PUT \ -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ -H "Content-Type: application/json" \ "${forge_url}/api/v1/repos/${repo_slug}/collaborators/${bot_user}" \ - -d "{\"permission\":\"${bot_perm}\"}" >/dev/null 2>&1 || true + -d '{"permission":"write"}' >/dev/null 2>&1 || true done - # Add disinto-admin as admin collaborator - curl -sf -X PUT \ - -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ - -H "Content-Type: application/json" \ - "${forge_url}/api/v1/repos/${repo_slug}/collaborators/disinto-admin" \ - -d '{"permission":"admin"}' >/dev/null 2>&1 || true - echo "Repo: ${repo_slug} created on Forgejo" else echo "Repo: ${repo_slug} (already exists on Forgejo)" @@ -938,51 +846,30 @@ setup_ops_repo() { "${forge_url}/api/v1/repos/${ops_slug}" >/dev/null 2>&1; then echo "Ops repo: ${ops_slug} (already exists on Forgejo)" else - # Create ops repo under org (or human user if org creation failed) + # Create ops repo under org if ! curl -sf -X POST \ -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ -H "Content-Type: application/json" \ "${forge_url}/api/v1/orgs/${org_name}/repos" \ -d "{\"name\":\"${ops_name}\",\"auto_init\":true,\"default_branch\":\"${primary_branch}\",\"description\":\"Operational data for ${org_name}/${ops_name%-ops}\"}" >/dev/null 2>&1; then - # Fallback: create under the human user namespace + # Fallback: create under the user curl -sf -X POST \ - -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ + -H "Authorization: token ${FORGE_TOKEN}" \ -H "Content-Type: application/json" \ - "${forge_url}/api/v1/users/johba/repos" \ + "${forge_url}/api/v1/user/repos" \ -d "{\"name\":\"${ops_name}\",\"auto_init\":true,\"default_branch\":\"${primary_branch}\",\"description\":\"Operational data\"}" >/dev/null 2>&1 || true fi - # Add all bot users as collaborators with appropriate permissions - # vault branch protection (#77) requires: - # - Admin-only merge to main (enforced by admin_enforced: true) - # - Bots can push branches and create PRs, but cannot merge - local bot_user bot_perm - declare -A bot_permissions=( - [dev-bot]="write" - [review-bot]="read" - [planner-bot]="write" - [gardener-bot]="write" - [vault-bot]="write" - [supervisor-bot]="read" - [predictor-bot]="read" - [architect-bot]="write" - ) - for bot_user in "${!bot_permissions[@]}"; do - bot_perm="${bot_permissions[$bot_user]}" + # Add all bot users as collaborators + local bot_user + for bot_user in dev-bot review-bot planner-bot gardener-bot vault-bot supervisor-bot predictor-bot; do curl -sf -X PUT \ -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ -H "Content-Type: application/json" \ "${forge_url}/api/v1/repos/${ops_slug}/collaborators/${bot_user}" \ - -d "{\"permission\":\"${bot_perm}\"}" >/dev/null 2>&1 || true + -d '{"permission":"write"}' >/dev/null 2>&1 || true done - # Add disinto-admin as admin collaborator - curl -sf -X PUT \ - -H "Authorization: token ${admin_token:-${FORGE_TOKEN}}" \ - -H "Content-Type: application/json" \ - "${forge_url}/api/v1/repos/${ops_slug}/collaborators/disinto-admin" \ - -d '{"permission":"admin"}' >/dev/null 2>&1 || true - echo "Ops repo: ${ops_slug} created on Forgejo" fi @@ -1913,20 +1800,6 @@ p.write_text(text) local ops_root="/home/${USER}/${project_name}-ops" setup_ops_repo "$forge_url" "$ops_slug" "$ops_root" "$branch" - # Set up vault branch protection on ops repo (#77) - # This ensures admin-only merge to main, blocking bots from merging vault PRs - # Use HUMAN_TOKEN (johba) or FORGE_TOKEN (dev-bot) for admin operations - export FORGE_OPS_REPO="$ops_slug" - # Source env.sh to ensure FORGE_TOKEN is available - source "${FACTORY_ROOT}/lib/env.sh" - source "${FACTORY_ROOT}/lib/branch-protection.sh" - if setup_vault_branch_protection "$branch"; then - echo "Branch protection: vault protection configured on ${ops_slug}" - else - echo "Warning: failed to set up vault branch protection" >&2 - fi - unset FORGE_OPS_REPO - # Generate project TOML (skip if already exists) if [ "$toml_exists" = false ]; then # Prompt for CI ID if interactive and not already set via flag