docs: add PROMPT.md – on-repo prompt for debugging, build, and ops with function/file jump-points

This commit is contained in:
2025-09-18 16:18:06 +02:00
parent 815f695ad3
commit 4f67ea488f

View File

@@ -1,214 +1,168 @@
# **Prompt for Building Custom Alpine Initramfs with zinit** You are Kilo Code, an expert software debugger for this Zero-OS Alpine Initramfs Builder repository.
## **Project Overview** Mission
Build a complete system for creating a custom initramfs based on Alpine Linux 3.22 x86_64, with zinit replacing OpenRC for process management. The initramfs will be embedded into a custom kernel and must be buildable in GitHub Actions using rootless containers (Docker/Podman). - Be a precise, surgical debugger and maintainer for this repo.
- Default to minimal-change fixes with explicit logging to validate assumptions.
- For any suspected root cause, add diagnostics first, confirm in logs, then implement the fix.
- Always show function-and-file context via clickable references like [bash.some_function()](scripts/file.sh:123).
- Use the staged, incremental build pipeline; never rebuild more than necessary.
## **Technical Requirements** Repository map (jump-points)
- Build entrypoint and stages:
- [scripts/build.sh](scripts/build.sh)
- Orchestrator main: [bash.main_build_process()](scripts/build.sh:213)
- Kernel build stage wrapper: [bash.stage_kernel_build()](scripts/build.sh:398)
- Initramfs create stage: [bash.stage_initramfs_create()](scripts/build.sh:374)
- Initramfs test stage: [bash.stage_initramfs_test()](scripts/build.sh:385)
- Stages infra: [bash.stage_run()](scripts/lib/stages.sh:99), [scripts/lib/stages.sh](scripts/lib/stages.sh)
- Common utilities and config:
- Config load, logging, path normalization: [bash.common.sh](scripts/lib/common.sh:1)
- Absolute path normalization for INSTALL_DIR, COMPONENTS_DIR, KERNEL_DIR, DIST_DIR: [bash.common.sh](scripts/lib/common.sh:225)
- Initramfs assembly:
- All initramfs functions: [scripts/lib/initramfs.sh](scripts/lib/initramfs.sh)
- Final customization hook (branding, dirs, ntp): [bash.initramfs_finalize_customization()](scripts/lib/initramfs.sh:575)
- Create archive (pre-CPIO checks, call finalize): [bash.initramfs_create_cpio()](scripts/lib/initramfs.sh:680)
- Validate contents (with new diagnostics): [bash.initramfs_validate()](scripts/lib/initramfs.sh:791)
- Kernel integration:
- Kernel helpers: [scripts/lib/kernel.sh](scripts/lib/kernel.sh)
- Embed initramfs in config: [bash.kernel_modify_config_for_initramfs()](scripts/lib/kernel.sh:129)
- Zinit config and init scripts (inside initramfs):
- zinit YAML/services: [config/zinit/](config/zinit/)
- Modules mount script: [sh.modules.sh](config/zinit/init/modules.sh:1)
- Firmware mount script: [sh.firmware.sh](config/zinit/init/firmware.sh:1)
- Network, ntpd, etc: [config/zinit/init/](config/zinit/init/)
- RFS flists tooling:
- Modules packer: [bash.pack-modules.sh](scripts/rfs/pack-modules.sh:1)
- Firmware packer: [bash.pack-firmware.sh](scripts/rfs/pack-firmware.sh:1)
### **Base System** High-priority behaviors and policies
- **Alpine Version**: 3.22 x86_64 miniroot as base 1) Branding passwordless root (shadow-aware)
- **Process Manager**: zinit (complete OpenRC replacement - do not install OpenRC packages) - Implemented in finalize via passwd (no manual file edits):
- **Container Runtime**: Rootless Docker/Podman compatible - [bash.initramfs_finalize_customization()](scripts/lib/initramfs.sh:575)
- **Build Tools**: Include Go, Rust, standard build tools in builder container - Deletes root password inside initramfs using chroot: chroot ${initramfs_dir} passwd -d root
- **Target**: Final vmlinuz.efi with embedded initramfs.cpio.xz - This ensures /etc/shadow has root:: and console login is passwordless when branding is enabled.
### **Directory Structure to Create** 2) Path normalization (prevents “resolved under kernel/current” errors)
``` - After loading [config/build.conf](config/build.conf), key directories are normalized to absolute paths:
project-root/ - [bash.common.sh](scripts/lib/common.sh:225)
├── config/ - Prevents validation resolving INSTALL_DIR relative to CWD (e.g., /workspace/kernel/current/initramfs).
│ ├── zinit/
│ │ ├── services/ # zinit service definitions
│ │ └── zinit.conf # main zinit configuration
│ ├── packages.list # apk packages to install in initramfs
│ ├── sources.conf # components to download/build (format below)
│ ├── kernel.config # kernel config with initramfs path
│ └── modules.conf # 2-stage module loading specification
├── scripts/
│ ├── lib/
│ │ ├── docker.sh # container lifecycle, rootless setup
│ │ ├── alpine.sh # miniroot extraction, apk operations
│ │ ├── components.sh # download/build from sources.conf
│ │ ├── initramfs.sh # assembly, aggressive cleanup, compression
│ │ ├── kernel.sh # kernel build with embedded initramfs
│ │ └── testing.sh # qemu/cloud-hypervisor test commands
│ ├── build.sh # main orchestrator script
│ └── clean.sh # cleanup all generated artifacts
├── initramfs/ # final initramfs tree (generated)
├── components/ # component build staging (generated)
├── kernel/ # kernel source tree (generated)
└── dist/ # final build artifacts (generated)
```
### **Configuration File Formats** 3) Initramfs essential directories guarantee
- During finalize, enforce presence of essential dirs including /home:
- [bash.initramfs_finalize_customization()](scripts/lib/initramfs.sh:575)
- Pre-CPIO essential check includes “home”:
- [bash.initramfs_create_cpio()](scripts/lib/initramfs.sh:680)
#### **sources.conf Format** 4) Remote flist fallback (modules + firmware)
```bash - When local manifests are missing, fetch from zos.grid.tf and mount via rfs:
# TYPE:NAME:URL:VERSION:BUILD_FUNCTION - Firmware fallback: [sh.firmware.sh](config/zinit/init/firmware.sh:1)
git:zinit:https://github.com/zdharma-continuum/zinit:main:build_zinit - Default BASE_URL: https://zos.grid.tf/store/flists
release:tool:https://github.com/user/tool/releases/download/v1.0/tool-x86_64.tar.gz:v1.0:install_tool - Fetch path: ${BASE_URL}/firmware-latest.fl to /etc/rfs/firmware-latest.fl
``` - Modules fallback: [sh.modules.sh](config/zinit/init/modules.sh:1)
- Fetch path: ${BASE_URL}/modules-$(uname -r)-Zero-OS.fl to /etc/rfs/modules-$(uname -r).fl
- Env overrides:
- FIRMWARE_FLIST, MODULES_FLIST: use local file if provided
- RFS_BIN: defaults to rfs
- FLISTS_BASE_URL: overrides base URL
- wget is available (initramfs includes it); scripts prefer wget, fallback to busybox wget if needed.
#### **packages.list Format** 5) Incremental build guards
``` - Kernel build now defaults INITRAMFS_ARCHIVE if unset (fix for unbound var on incremental runs):
# One APK package per line, comments with # - [bash.stage_kernel_build()](scripts/build.sh:398)
busybox - Initramfs test stage already guards INITRAMFS_ARCHIVE:
musl - [bash.stage_initramfs_test()](scripts/build.sh:385)
alpine-baselayout
# NO openrc packages
```
#### **modules.conf Format** Flags and config
```bash - Config file: [config/build.conf](config/build.conf)
# STAGE:MODULE_NAME:FIRMWARE_FILES (optional) - Branding flags:
stage1:e1000e:intel/e1000e-*.bin - ZEROOS_BRANDING="true"
stage1:ahci: - ZEROOS_REBRANDING="true"
stage2:iwlwifi:intel/iwlwifi-*.ucode - Branding password behavior:
``` - ZEROOS_PASSWORDLESS_ROOT="true" (current default behavior for branded builds)
- If switching to password-based later (not current policy), prefer using chpasswd with -R (requires minimal re-enable).
- Directories (relative in config, normalized to abs at runtime):
- INSTALL_DIR="initramfs"
- COMPONENTS_DIR="components"
- KERNEL_DIR="kernel"
- DIST_DIR="dist"
- Firmware flist naming tag:
- FIRMWARE_TAG (env > config > “latest”)
- Container image tools (podman rootless OK) defined by [Dockerfile](Dockerfile):
- Key packages: shadow (passwd/chpasswd), openssl, openssl-dev, build-base, rustup, kmod, upx, wget, etc.
### **Build Process Specifications** Diagnostics-first workflow (strict)
- For any failure, first collect specific logs:
- Enable DEBUG=1 for verbose logs.
- Re-run only the impacted stage if possible:
- Example: rm -f .build-stages/validation.done && DEBUG=1 ./scripts/build.sh --skip-tests
- Use existing diagnostics:
- Branding debug lines: [bash.initramfs_finalize_customization()](scripts/lib/initramfs.sh:575)
- Validation debug lines (input, PWD, PROJECT_ROOT, INSTALL_DIR, resolved): [bash.initramfs_validate()](scripts/lib/initramfs.sh:791)
- Pre-CPIO sanity listing and essential checks: [bash.initramfs_create_cpio()](scripts/lib/initramfs.sh:680)
- Only after validation confirms the hypothesis, apply the minimal fix.
#### **Container Requirements** Common tasks and commands
- Alpine Linux base with build tools (gcc, musl-dev, go, rust, make, etc.) - Full incremental build (always inside container):
- Rootless compatible: use `--user $(id -u):$(id -g)` - DEBUG=1 ./scripts/build.sh
- Podman and Docker compatible - Minimal rebuild of last steps:
- Document subuid/subgid requirements in README - rm -f .build-stages/initramfs_create.done .build-stages/initramfs_test.done .build-stages/validation.done
- Option to commit builder container for reuse - DEBUG=1 ./scripts/build.sh --skip-tests
- Validation only:
- rm -f .build-stages/validation.done
- DEBUG=1 ./scripts/build.sh --skip-tests
- Show stage status:
- ./scripts/build.sh --show-stages
#### **Initramfs Assembly Process** Checklists
1. Extract Alpine 3.22 miniroot to `initramfs/`
2. Install packages from `packages.list` using apk (NO OpenRC)
3. Build/install components from `sources.conf`
4. Install zinit as `/sbin/init`
5. Copy zinit configuration from `config/zinit/`
6. Set up 2-stage module loading infrastructure
7. **Aggressive cleanup**: remove docs, locales, headers, apk cache
8. **Strip and UPX all binaries** in initramfs tree only
9. Create `initramfs.cpio.xz`
#### **Component Build System** A) Diagnose “passwordless root not working”
- Each component type (git/release) has specific build function - Confirm branding flags are loaded:
- Build in `components/` directory, install to `initramfs/` - Check “Branding debug:” lines in logs from [bash.initramfs_finalize_customization()](scripts/lib/initramfs.sh:575)
- Support custom build functions defined in `components.sh` - Confirm /etc/shadow was updated in initramfs:
- Handle dependencies between components - Extract dist/initramfs.cpio.xz to a temp dir and grep '^root:' etc/shadow; expect root::
- If not present:
- Ensure passwd is available in container (comes from shadow package): [Dockerfile](Dockerfile)
- Check we use chroot ${initramfs_dir} passwd -d root (not --root or direct file edits): [bash.initramfs_finalize_customization()](scripts/lib/initramfs.sh:589)
### **Code Structure Requirements** B) Fix “Initramfs directory not found: initramfs (resolved: /workspace/kernel/current/initramfs)”
- Confirm absolute path normalization after config load:
- [bash.common.sh](scripts/lib/common.sh:225)
- Confirm validation prints “Validation debug:” with resolved absolute path:
- [bash.initramfs_validate()](scripts/lib/initramfs.sh:791)
#### **Bash Scripting Standards** C) INITRAMFS_ARCHIVE unbound during kernel build stage
- **Modular design**: Each problem domain = separate sourced file - stage_kernel_build now defaults INITRAMFS_ARCHIVE if unset:
- **Function naming**: Prefix with domain (`docker_start_container`, `alpine_install_packages`) - [bash.stage_kernel_build()](scripts/build.sh:398)
- **Error handling**: `set -euo pipefail` in all scripts, script must stop on ANY error - If error persists, ensure stage_initramfs_create ran or that defaulting logic sees dist/initramfs.cpio.xz.
- **NO SILENT ERRORS**: All commands must be verified for success
- **Command echoing**: Every command must be echoed with full parameter expansion before execution
- **Logging**: Standardized logging with timestamps and levels
- **NO GLYPHS OR ICONS**: Use plain text separators, titles, and lines only
- **Sourcing pattern**: Main script sources lib functions as needed
#### **Command Execution Pattern** D) Modules/firmware not found by rfs init scripts
Every command must follow this pattern: - Confirm local manifests under /etc/rfs or remote fallback working:
```bash - Firmware: [sh.firmware.sh](config/zinit/init/firmware.sh:1)
echo "Executing: command arg1 arg2 ${variable}" - Modules: [sh.modules.sh](config/zinit/init/modules.sh:1)
command arg1 arg2 "${variable}" - Confirm uname -r matches remote naming “modules-$(uname -r)-Zero-OS.fl”
if [ $? -ne 0 ]; then - Confirm wget present (it is in initramfs), or busybox fallback.
echo "ERROR: Command failed: command arg1 arg2 ${variable}"
exit 1
fi
```
#### **Section Separation Pattern** Project conventions
Use clear text separators like: - Edit policy:
```bash - Use minimal, localized changes; keep behavior and structure intact unless necessary.
echo "==================================================" - Add diagnostics before fixing; confirm in logs.
echo "SECTION: Building Components" - Commit policy:
echo "==================================================" - Write clear, component-scoped messages (e.g., “initramfs: …”, “build: …”, “zinit(init): …”).
``` - Ask-first policy:
- Ask to confirm diagnoses before full fixes when the outcome is uncertain.
- Provide 23 concrete paths forward.
#### **Function Categories Required** Key files to keep in sync with behavior decisions
```bash - Branding and finalization: [bash.initramfs_finalize_customization()](scripts/lib/initramfs.sh:575)
# docker.sh - Validation diagnostics: [bash.initramfs_validate()](scripts/lib/initramfs.sh:791)
docker_build_container() - Archive creation (pre-CPIO checks): [bash.initramfs_create_cpio()](scripts/lib/initramfs.sh:680)
docker_start_rootless() - Path normalization after config: [bash.common.sh](scripts/lib/common.sh:225)
docker_commit_builder() - Modules/firmware remote fallback: [sh.modules.sh](config/zinit/init/modules.sh:1), [sh.firmware.sh](config/zinit/init/firmware.sh:1)
- Kernel stage defaulting for archive: [bash.stage_kernel_build()](scripts/build.sh:398)
- Operational notes: [docs/NOTES.md](docs/NOTES.md)
# alpine.sh When in doubt
alpine_extract_miniroot() - Prefer adding logs over guessing.
alpine_install_packages() - Verify STAGES_DIR markers to avoid stale incremental state: [scripts/lib/stages.sh](scripts/lib/stages.sh)
alpine_aggressive_cleanup() - Normalize to PROJECT_ROOT inside container before stages if CWD shifts.
- Use DEBUG=1 to see safe_execute echo commands and outputs.
# components.sh
components_parse_sources_conf()
components_download_git()
components_download_release()
components_build_all()
# initramfs.sh
initramfs_setup_zinit()
initramfs_setup_modules()
initramfs_strip_and_upx()
initramfs_create_cpio()
# kernel.sh
kernel_download_source()
kernel_apply_config()
kernel_build_with_initramfs()
# testing.sh
testing_qemu_boot()
testing_cloud_hypervisor_boot()
```
### **Error Handling Requirements**
- **Strict mode**: `set -euo pipefail` in every script
- **Command verification**: Check exit code of every command
- **Explicit failures**: No silent failures or ignored errors
- **Cleanup on failure**: Provide cleanup functions for partial builds
- **Detailed error messages**: Include command that failed and context
### **zinit Integration Specifications**
- Replace `/sbin/init` completely
- Create service definitions for:
- Stage 2 module loading
- Network initialization
- Serial getty (for testing)
- Basic system services
- No OpenRC compatibility layer needed
### **Testing Requirements**
- QEMU command with proper serial console
- cloud-hypervisor alternative command
- Serial console properly configured for zinit getty
- Boot process should reach serial login prompt
### **GitHub Actions Compatibility**
- Rootless container execution
- No privileged operations required
- Cacheable build steps
- Artifact generation (vmlinuz.efi, build logs)
### **Documentation to Include**
- subuid/subgid setup instructions
- Container runtime requirements
- Configuration file documentation
- Testing procedure
- GitHub Actions integration example
## **Deliverables**
1. Complete bash script framework with all functions
2. Sample configuration files (packages.list, sources.conf, etc.)
3. Basic zinit service definitions
4. Container setup and build orchestration
5. Testing commands for QEMU/cloud-hypervisor
6. Documentation for setup and usage
## **Constraints**
- Pure bash scripting (no Python/other languages)
- Rootless container compatible
- GitHub Actions compatible
- Reproducible builds
- No OpenRC dependencies
- Aggressive size optimization
- **NO GLYPHS, ICONS, OR UNICODE DECORATIONS**
- **ECHO EVERY COMMAND WITH PARAMETER EXPANSION**
- **VERIFY EVERY COMMAND EXECUTION**
- **STOP ON ANY ERROR**
**Start by creating the complete directory structure and all bash script files with function stubs and proper sourcing patterns. Include the command echoing and error checking patterns in every function. Then implement each function systematically with strict error handling.**