Files
ngn-agent/.planning/phases/09-tooling-portable-setup/09-02-SUMMARY.md
Bagas Purwa Sentika 4520237754 docs(09-tooling-portable-setup-02): complete portable setup script plan
- Created 1340-line standalone setup-ngn-agent.sh with argument parsing,
  prereq checks, masked secret prompts, config generation, embedded skills/scripts,
  cron registration, and gateway restart offer
- All 3 tasks committed atomically
2026-06-15 23:31:30 +08:00

168 lines
8.8 KiB
Markdown

---
phase: 09-tooling-portable-setup
plan: 02
subsystem: setup
tags: [bash, hermes, setup-script, provisioning, cron, skills]
requires:
- phase: 08-cron-reporting
plan: 01
provides: archive-stale-sessions.sh script content, cron registration patterns (hermes cron create CLI syntax, DRY_RUN pattern)
- phase: 08-cron-reporting
plan: 02
provides: Weekly cron job patterns (ngn-weekly-stale-summary, ngn-weekly-archive) with 5-minute offset between summary and archive
- phase: 07-main-session-skill
provides: session skill SKILL.md content for embedding; hindsight_retain templates, Jira ticket creation pattern with epic cache
- phase: 04-jira-skill
provides: jira-query skill SKILL.md content for embedding
provides:
- ngn-agent/setup-ngn-agent.sh — 1340-line standalone portable setup script with embedded file snapshots
- All 5 skill files + 2 reference files embedded as heredocs for self-contained re-creation
- Config generation: config.yaml (via hermes config set + Python yaml), .env (with chmod 600), hindsight/config.json
- 3 cron job registrations (ngn-daily-report, ngn-weekly-stale-summary, ngn-weekly-archive)
- Interactive secret prompts with masked input (T-09-05 mitigation)
- Best-effort error handling pattern for non-critical steps
affects:
- Phase 10+ (any phase needing to regenerate ngn-agent configuration on a new machine)
tech-stack:
added: []
patterns:
- Standalone portable setup script with embedded heredocs (no external file dependencies)
- Hybrid config generation: hermes config set for scalars + Python yaml (fallback sed) for arrays
- prompt_secret function with env-var skip, masked input, loop-until-nonempty
- Best-effort error handling: non-critical steps wrapped with || true
- Progress indicator pattern [N/14] for step-by-step execution
key-files:
created:
- ngn-agent/setup-ngn-agent.sh — 1340-line portable setup script
modified: []
key-decisions:
- "Each embedded file is a separate write function (write_session_init, write_jira_skill, etc.) — self-documenting and independently testable"
- "Config.yaml uses hybrid approach: hermes config set for scalar keys, Python yaml module for arrays, sed fallback when yaml unavailable"
- "Skill and script files embedded as heredocs with quoted delimiters ('EOF') — prevents variable expansion at script generation time"
- "Cron registration wrapped with 2>/dev/null + 'may already exist' message — idempotent re-runs"
- "Non-interactive mode (-y) reads secrets from environment variables with : ${VAR:?error} validation"
patterns-established:
- "Standalone portable setup script pattern: argument parsing → prereq checks → secret prompts → file generation → cron registration → restart offer"
- "Embedded heredoc pattern: each file is a bash function with cat > path << 'QUOTED_DELIM' to prevent variable expansion in embedded content"
- "Hybrid YAML generation: hermes config set for scalars, Python yaml for arrays, sed fallback"
requirements-completed: [SETUP-01]
duration: 4 min
completed: 2026-06-15
---
# Phase 9 Plan 2: Portable ngn-agent Setup Script Summary
**Portable 1340-line standalone bash setup script (ngn-agent/setup-ngn-agent.sh) for recreating all ngn-agent Hermes configuration on a fresh macOS machine — argument parsing, interactive secrets, config YAML/env/hindsight generation, all 5 skills + 2 scripts embedded, 3 cron jobs registered, gateway restart offer**
## Performance
- **Duration:** 4 min
- **Started:** 2026-06-15 23:26 +08
- **Completed:** 2026-06-15 23:30 +08
- **Tasks:** 3
- **Files modified:** 1 (1340 lines added)
## Accomplishments
- Created `setup-ngn-agent.sh` (1340 lines) — fully self-contained, no external file dependencies
- Argument parsing with getopts for 9 configurable parameters (SSH keys, repo paths, timezone, docker image)
- Prerequisite validation: Hermes CLI on PATH, Docker running, SSH key file existence, repo path existence
- Interactive masked secret prompts for JIRA_API_TOKEN, JIRA_EMAIL, TELEGRAM_BOT_TOKEN, OPENROUTER_API_KEY (T-09-05)
- Config generation via hermes config set (scalars) + Python yaml (arrays) + sed fallback
- .env generation with chmod 600 permissions (T-09-06)
- hindsight/config.json with local_embedded mode, qwen/qwen3.5-9b model, hybrid memory
- All 5 skills (jira, aws-diagnostics, confluence, bitbucket, session) + 2 reference files embedded as heredocs
- Both scripts (session-init.sh, archive-stale-sessions.sh) embedded as heredocs with executable permission
- 3 cron jobs registered with proper schedules and delivery methods
- Config.yaml backup before modification (T-09-07)
- Gateway restart offer at completion
- Non-interactive mode (-y) for automated provisioning
## Task Commits
Each task was committed atomically:
1. **Task 1: Create setup script skeleton — args, prereqs, and interactive prompts** - `2de51b1` (feat)
2. **Task 2: Implement config generation — config.yaml, .env, hindsight/config.json** - `9da9728` (feat)
3. **Task 3: Implement file/cron setup — scripts, skills, cron registration, gateway restart** - `5a8c183` (feat)
## Files Created/Modified
- `ngn-agent/setup-ngn-agent.sh` — 1340-line standalone portable setup script (created)
## Decisions Made
- **Embedded heredocs over base64**: All skill files, scripts, and reference files are embedded using heredocs with quoted delimiters (`'EOF'`) — prevents variable expansion at script generation time, keeps content human-readable without encoding overhead. Each file is a separate bash function for modularity and independent testing.
- **Hybrid config.yaml generation**: `hermes config set` for scalar keys (docker_image, memory.provider, timezone, etc.) + Python yaml module for arrays (docker_volumes, shell_init_files, docker_forward_env). Python's yaml.safe_load → modify → yaml.dump preserves unknown keys and maintains proper YAML formatting. Fallback to sed-based injection if the `yaml` Python module is unavailable.
- **Best-effort error handling**: The script uses `set -euo pipefail` for strict mode, but non-critical steps like cron registration are wrapped with `|| echo "⚠ ..."` — allowing the script to continue if a cron job already exists or if the Hermes CLI returns a non-fatal error.
- **Prompt_secret with env-var skip**: Secret prompts check if the environment variable is already set before prompting (supports pre-exported secrets or non-interactive mode via `-y` flag).
- **Cron job registration order**: Daily report first (most critical), then weekly summary, then weekly archive. Archive runs 5 minutes after summary (20:05 vs 20:00) per Phase 8 pattern to prevent race conditions.
## Deviations from Plan
None — plan executed exactly as written.
## Issues Encountered
None. All three tasks completed cleanly with syntax validation passing (`bash -n`).
## User Setup Required
**External services require manual configuration.** See [09-USER-SETUP.md](./09-USER-SETUP.md) for:
- Hermes CLI v0.16+ installation (pre-requisite)
- JIRA_API_TOKEN from https://id.atlassian.com/manage/api-tokens
- TELEGRAM_BOT_TOKEN from https://t.me/BotFather
- OPENROUTER_API_KEY from https://openrouter.ai/keys
The setup script handles interactive prompting for all 4 secrets.
## Threat Flags
None — all threat mitigations from the plan's threat model are satisfied:
- T-09-05 (Information Disclosure — secret exposure in terminal history): Mitigated — `read -s` for all secret prompts with masked input.
- T-09-06 (Information Disclosure — .env world-readable secrets): Mitigated — `chmod 600` on .env immediately after writing.
- T-09-07 (Tampering — config file corruption): Mitigated — backup existing config.yaml to `.bak.<timestamp>` before modification.
- T-09-08 (Information Disclosure — terminal scrollback): Accepted — users responsible for terminal security.
- T-09-09 (Tampering — cron prompt injection): Accepted — prompts embedded in setup script, not user-controllable.
## Next Phase Readiness
- Phase 9 Plan 1 (Docker custom image) complete, Plan 2 (setup script) complete
- Phase 9 fully complete — both Dockerfile + build script and portable setup script artifacts ready
- User can run `setup-ngn-agent.sh --help` to see all parameters
- Dry-run: user can run `bash -x setup-ngn-agent.sh` to trace execution (no destructive test needed)
- Ready for next phase (v1.1 milestone completion, validation, or v1.2 planning)
## Self-Check: PASSED
| Check | Result |
|-------|--------|
| File exists | ✓ setup-ngn-agent.sh (1340 lines) |
| File executable | ✓ |
| Syntax validation (`bash -n`) | ✓ |
| Task 1 commit (2de51b1) | ✓ |
| Task 2 commit (9da9728) | ✓ |
| Task 3 commit (5a8c183) | ✓ |
| Script ≥ 300 lines | ✓ (1340 lines) |
| `hermes cron create` count = 3 | ✓ |
| Function names ≥ 8 matched | ✓ (14 matches) |
| SUMMARY.md exists | ✓ |
---
*Phase: 09-tooling-portable-setup*
*Completed: 2026-06-15*