Skip to content

feat(#4912): add --config and --config-hash preset install flags - #5953

Merged
ifireball merged 2 commits into
mainfrom
agent/4912-config-preset-flags
Aug 6, 2026
Merged

feat(#4912): add --config and --config-hash preset install flags#5953
ifireball merged 2 commits into
mainfrom
agent/4912-config-preset-flags

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Summary

Adds --config and --config-hash flags to fullsend github setup <owner/repo> for installing vendor-curated configuration presets per ADR 0069 Decision 3.

When --config <path-or-url> is provided, the installer:

  1. Fetches/reads the preset document (local file or HTTPS URL)
  2. Validates content against --config-hash <sha256> when supplied (hash mismatch aborts before commit)
  3. Commits the preset as .fullsend/config.base.yaml in the target repository
  4. Writes a stub .fullsend/config.yaml with comments and minimal empty override fields

Without --config, the existing per-repo setup behavior is unchanged.

Changes

  • internal/cli/preset.go: fetchPreset (local/HTTPS), validatePresetHash (SHA-256), and stubConfigYAML constant
  • internal/cli/github.go: configPreset/configHash fields, flag registration, --config-hash requires --config validation, and preset integration in runGitHubSetupPerRepo
  • internal/cli/preset_test.go: Unit tests covering fetch (local file, HTTPS, missing, empty, unsupported scheme), hash validation (match, mismatch, uppercase, invalid length/hex), CLI flag presence, flag validation errors, dry-run paths, file layout verification (base + stub committed, no base without --config), and error handling

Testing

  • All new and existing github CLI tests pass (go test -race -run "TestGitHub|TestParseTarget|TestRunGitHub|TestConfig|TestFetchPreset|TestValidatePresetHash")
  • go vet ./internal/cli/ passes
  • Pre-existing test failure in TestPostScriptEnv_NoSchemaAppendedWhenNoValidationLoop is unrelated (run_test.go)
  • Secret scan clean

Closes #4912

Post-script verification

  • Branch is not main/master (agent/4912-config-preset-flags)
  • Secret scan passed (gitleaks — 8549ba72c380c8d969a6620c0a94f2abd30898d5..HEAD)
  • PR body secret scan passed (gitleaks — no-git)

Add support for vendor-curated configuration presets in per-repo
setup. When --config is provided with a local file path or HTTPS
URL, the installer fetches the preset and commits it as
.fullsend/config.base.yaml in the target repository. A stub
.fullsend/config.yaml overlay with comments and minimal fields
is generated alongside.

The optional --config-hash flag accepts a SHA-256 hex digest.
When supplied, the fetched preset content is validated against
the hash before any commit; a mismatch aborts the operation.

Without --config, the existing per-repo setup behavior is
unchanged — a full config.yaml is generated from CLI flags.

Implementation details:
- preset.go: fetchPreset (local file / HTTPS), validatePresetHash
  (SHA-256), and stubConfigYAML constant
- github.go: configPreset/configHash fields on githubSetupConfig,
  flag registration, validation, and integration into
  runGitHubSetupPerRepo
- preset_test.go: unit tests for fetch, hash validation, CLI
  flag presence, hash-without-config error, dry-run with preset,
  dry-run with hash match/mismatch, file layout verification
  (base + stub committed), backward compatibility (no base
  without --config), and missing-file error handling

Note: pre-commit could not run in sandbox (network restriction
during hook init). Post-script runs authoritative pre-commit.

Closes #4912
@fullsend-ai-coder
fullsend-ai-coder Bot requested a review from a team as a code owner August 5, 2026 19:46
@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Triggers review agent dispatch label Aug 5, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 5, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:47 PM UTC · Completed 8:04 PM UTC
Commit: 5efbc73 · View workflow run →

@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.45455% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/cli/preset.go 84.74% 6 Missing and 3 partials ⚠️
internal/cli/github.go 86.27% 4 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review

Findings

Low

  • [SSRF-internal-network] internal/cli/preset.go:63fetchPresetHTTPS makes outbound HTTP requests to user-supplied URLs. While the CheckRedirect policy correctly blocks non-HTTPS redirects, there is no restriction on the target hostname. In practice, this is a local CLI tool invoked by an operator with shell access who already has equivalent network access.
    Remediation: No action required for the current threat model. If this code path is ever exposed to untrusted input, add hostname allowlisting.

  • [path-traversal] internal/cli/preset.go:49fetchPresetLocal passes the user-supplied path directly to os.ReadFile without sanitization. However, the operator providing --config already has shell access with equivalent filesystem reach. Read-only, no privilege escalation.
    Remediation: No action needed for the current threat model.

Previous run

Review

Findings

High

  • [stale-doc] docs/cli/github.md:43 — The flags table for github setup documents existing flags but does not mention the new --config and --config-hash flags introduced by this PR. Users consulting the CLI reference will not discover these flags.
    Remediation: Add rows for --config and --config-hash to the flags table.

Medium

  • [silent-flag-ignoring] internal/cli/github.go — When --config is provided, the --runtime and --agents flags are silently ignored. The preset path skips perRepoCfg generation (including SetRuntime and role embedding), but no validation warns the user. A user passing --config preset.yaml --runtime claude would reasonably expect the runtime to be set, but it is silently dropped.
    Remediation: Check if --runtime or --agents were explicitly changed (via cmd.Flags().Changed()) when --config is also set, and return an error.

  • [SSRF-TLS-downgrade] internal/cli/preset.go:49fetchPresetHTTPS uses Go's default http.Client which follows up to 10 redirects without restriction. Although the entry-point URL is validated to be https://, a redirect can downgrade to http:// or reach internal network addresses. The scheme gate only checks the initial URL.
    Remediation: Set a CheckRedirect policy on the http.Client that rejects redirects to non-HTTPS URLs.

  • [missing-doc] docs/guides/getting-started/configuring-github.md:58 — The setup guide shows only the flag-based installation path but does not mention the new preset-based installation option with --config.
    Remediation: Add a section showing the preset-based alternative.

Low

  • [silent-flag-ignoring] internal/cli/github.go--config and --config-hash are silently ignored in per-org mode (fullsend github setup <org>). The flags are registered on the shared command but runGitHubSetupPerOrg never reads cfg.configPreset.
    Remediation: Add config/config-hash to a per-repo-only validation block, or document the limitation.

  • [integrity-optional-hash] internal/cli/github.go:222--config-hash is optional by design (per issue feat(install): --config and --config-hash preset install flags (ADR 0069) #4912). When --config is provided without --config-hash, remote content is committed without integrity verification. A warning when fetching remote preset content without hash pinning would improve UX.
    Remediation: Log a warning when fetching remote presets without --config-hash.

  • [missing-validation] internal/cli/preset.go — Preset content is committed as config.base.yaml without YAML validity checking. Malformed content is committed and only fails at runtime.
    Remediation: Parse preset data as YAML before committing for fail-fast behavior.

  • [missing-validation] internal/cli/preset.gofetchPresetLocal does not enforce the presetMaxSize limit (1 MiB), while fetchPresetHTTPS does. Asymmetric size enforcement.
    Remediation: Add a size check after os.ReadFile in fetchPresetLocal.

  • [stale-doc] docs/guides/infrastructure/advanced-setup.md:16 — The platform-provided infrastructure section does not mention that operators can distribute a preset URL instead of requiring multiple flags.
    Remediation: Add a note about preset-based installation for platform operators.

  • [flag-description-style] internal/cli/github.go:154 — Flag description for --config says "path or HTTPS URL" — "local file path or HTTPS URL" would be clearer.
    Remediation: Expand the flag description slightly.


Labels: PR adds new --config/--config-hash install flags to the github setup CLI command


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added the component/install CLI install and app setup label Aug 5, 2026
@ifireball

Copy link
Copy Markdown
Member

/fs-fix

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 5:55 AM UTC · Completed 6:06 AM UTC
Commit: 5efbc73 · View workflow run →

- Add CheckRedirect policy to reject non-HTTPS redirects (SSRF fix)
- Reject --runtime/--agents when --config is set (silent flag ignoring)
- Reject --config/--config-hash in per-org mode (per-repo only)
- Add YAML syntax validation before committing preset content
- Enforce presetMaxSize limit in fetchPresetLocal (parity with HTTPS)
- Warn when remote preset fetched without --config-hash
- Expand --config flag description to "local file path or HTTPS URL"
- Add --config and --config-hash to CLI reference flags table
- Add vendor preset section to getting-started and advanced-setup docs
- Add tests for all new validations

Addresses review feedback on #5953
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (human-triggered)

Addressed all 10 review findings: SSRF redirect protection, flag interaction validation (--runtime/--agents with --config, --config in per-org mode), YAML syntax validation, symmetric size limits, remote-without-hash warning, flag description clarity, and documentation updates across CLI reference, getting-started guide, and advanced setup guide. Added tests for all new validations.

Fixed (10):

  1. stale-doc: CLI flags table missing --config and --config-hash (docs/cli/github.md): Added rows for --config and --config-hash to the flags table in the CLI reference
  2. silent-flag-ignoring: --runtime and --agents silently ignored when --config is set (internal/cli/github.go): Added validation in RunE that returns an error when --runtime or --agents are explicitly changed alongside --config
  3. SSRF-TLS-downgrade: fetchPresetHTTPS follows redirects to non-HTTPS URLs (internal/cli/preset.go): Added CheckRedirect policy that rejects any redirect to a non-HTTPS URL
  4. missing-doc: setup guide missing preset-based installation option (docs/guides/getting-started/configuring-github.md): Added 'Using a vendor preset' section showing --config/--config-hash usage
  5. silent-flag-ignoring: --config and --config-hash silently ignored in per-org mode (internal/cli/github.go): Added validation in RunE that returns an error when --config or --config-hash is used with a per-org target
  6. integrity-optional-hash: no warning when fetching remote preset without --config-hash (internal/cli/github.go): Added printer.StepWarn when a remote preset is fetched without --config-hash
  7. missing-validation: preset content not checked for YAML validity before commit (internal/cli/preset.go): Added validatePresetYAML that parses content as YAML before committing; called in runGitHubSetupPerRepo
  8. missing-validation: fetchPresetLocal does not enforce presetMaxSize limit (internal/cli/preset.go): Added size check after os.ReadFile in fetchPresetLocal to match the HTTPS path
  9. stale-doc: advanced-setup.md missing preset mention for platform operators (docs/guides/infrastructure/advanced-setup.md): Added a paragraph and code example about vendor presets in the platform-provided infrastructure section
  10. flag-description-style: --config flag description unclear about local paths (internal/cli/github.go): Changed flag description from 'path or HTTPS URL' to 'local file path or HTTPS URL'

Tests: passed

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 6, 2026

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 6:08 AM UTC · Ended 6:21 AM UTC
Commit: 0855647 · View workflow run →

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Site preview

Preview: https://c5185f56-site.fullsend-ai.workers.dev

Commit: 085564756d5f17c26d6079dc37e1d651c0eacaef

@fullsend-ai-review
fullsend-ai-review Bot dismissed their stale review August 6, 2026 06:21

Superseded by updated review

Comment thread internal/cli/preset.go
Comment thread internal/cli/preset.go
@fullsend-ai-review fullsend-ai-review Bot added the ready-for-merge All reviewers approved — ready to merge label Aug 6, 2026
@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:08 AM UTC · Completed 6:21 AM UTC
Commit: 0855647 · View workflow run →

@ifireball
ifireball added this pull request to the merge queue Aug 6, 2026
Merged via the queue into main with commit 49fdc20 Aug 6, 2026
24 of 25 checks passed
@ifireball
ifireball deleted the agent/4912-config-preset-flags branch August 6, 2026 08:48
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 6, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 8:50 AM UTC · Completed 9:04 AM UTC
Commit: 0855647 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #5953feat(#4912): add --config and --config-hash preset install flags

Timeline

Time (UTC) Event
Aug 5 19:27 ifireball triggers /fs-code on issue #4912
Aug 5 19:28–19:46 Code agent produces implementation (772 additions, 6 files, 85% patch coverage)
Aug 5 19:46 PR #5953 created by fullsend-ai-coder[bot]
Aug 5 19:47 Two review runs dispatched; first cancelled in 17s, second runs to completion
Aug 5 20:04 Review completes with 10 findings: 1 high (stale docs), 3 medium (SSRF-TLS-downgrade, silent flag ignoring, missing guide), 6 low
Aug 6 05:54 ifireball triggers /fs-fix
Aug 6 05:55–06:06 Fix agent addresses all 10 findings in a single pass (~11 min)
Aug 6 06:07–06:21 Second review approves — only informational low-severity items remain
Aug 6 08:09 ifireball approves
Aug 6 08:48 PR merged

Assessment

This workflow performed well. The pipeline produced a solid outcome in two iterations (code → fix), which is the ideal minimum when the first review has legitimate findings.

Review quality was strong. The review agent caught a genuine security issue (SSRF via TLS-downgrade through HTTP redirect chain in fetchPresetHTTPS), three documentation gaps across docs/cli/github.md, docs/guides/getting-started/configuring-github.md, and docs/guides/infrastructure/advanced-setup.md, and several UX improvements (flag conflict validation, YAML syntax check, warning for unhashed remote presets). No false positives wasted human time. The second review correctly calibrated remaining low-severity items as acceptable for the local CLI threat model.

Fix agent was excellent. All 10 review findings were addressed in a single 11-minute pass, with no rework. The fix added SSRF redirect protection, flag conflict validation, YAML validation, size limit enforcement, a remote-without-hash warning, and complete documentation updates.

Code agent did well on implementation, less well on docs and security hardening. The initial 772-line implementation was functionally correct with comprehensive tests (514-line test file, 85% patch coverage). The gaps were: (1) three documentation files not updated when adding new CLI flags, and (2) using Go's default http.Client without a redirect policy for user-provided URLs.

Evidence for existing issues

  • #5848 (AGENTS.md CLI flag docs guidance): Direct evidence. The code agent added --config and --config-hash flags but did not update docs/cli/github.md. Note: AGENTS.md: add guidance to update docs/cli/ when changing CLI flag behavior #5848 scopes to docs/cli/ only, but this PR also missed docs/guides/ pages — the guidance should cover all of docs/ to be fully effective.
  • #3024 (AGENTS.md secure HTTP client guidance): Direct evidence. The code agent used a default http.Client with no redirect policy, creating an SSRF-TLS-downgrade vector that the review agent caught.
  • #1733 (Code agent proactive docs updates): Supporting evidence. The code agent did not update getting-started or infrastructure guides despite adding a user-facing feature.
  • #1452 (Deduplicate review dispatches for same HEAD SHA): Minor evidence. Two review runs were dispatched within 11 seconds of each other for the same HEAD SHA at PR creation; one was cancelled after 17 seconds.

No new proposals

All improvement opportunities identified are already tracked by open issues. Implementing #5848 (broadened to cover all docs/ paths) and #3024 would likely have eliminated the fix iteration entirely, as the code agent would have updated documentation and used a secure HTTP client pattern in the initial implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/install CLI install and app setup ready-for-merge All reviewers approved — ready to merge ready-for-review Triggers review agent dispatch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(install): --config and --config-hash preset install flags (ADR 0069)

1 participant