Skip to content

feat: explicit --mode / HOSTDOC_MODE + mode-derivation footgun warning (#39) - #48

Merged
jkas2016 merged 9 commits into
mainfrom
feat/39-explicit-mode-control
Jul 6, 2026
Merged

feat: explicit --mode / HOSTDOC_MODE + mode-derivation footgun warning (#39)#48
jkas2016 merged 9 commits into
mainfrom
feat/39-explicit-mode-control

Conversation

@jkas2016

@jkas2016 jkas2016 commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Closes #39.

문제

mode는 저장되지 않고 병합된 config에서 파생된다(domain+distributionId → cloudfront; serveRoot → self-hosted; else bucket+region → s3-website). 그래서 cloudfront config 파일 위에 HOSTDOC_BUCKET만 얹어도 파일의 domain이 파생을 이겨 s3-website로 못 바꾸고, 그 bucket은 경고 없이 조용히 무시됐다. mode를 강제할 env/flag도 없었다.

변경 (방향 B + D, C는 기각)

  • --mode / HOSTDOC_MODE 로 파생 mode를 강제 (s3-website | cloudfront | self-hosted). --mode flag > HOSTDOC_MODE env, 파일엔 저장/조회 안 함(파생값 원칙 유지). 강제한 mode의 필수 필드만 검증하고, 안 쓰는 필드는 무시 + stderr 경고.
  • 함정 자동 감지: mode 미지정인데 bucketdomain보다 높은 precedence로 줬는데도 cloudfront로 파생되면 stderr 경고(Use --mode s3-website to force s3-website.). 출처 레벨은 pick() 헬퍼로 추적.
  • 방향 C 기각: bucket precedence로 mode를 자동으로 뒤집지 않는다 — bucket은 cloudfront에서도 정상 필드라 더 놀랍고 위험. 강제(B)는 명시적, shadow는 경고만.
  • 경고는 stderr 전용(stdout 발행 링크 무오염). resolveConfig는 순수 유지 — 경고 출력은 주입식 opts.warn(기본 stderr).
  • README Configuration precedence 절에 --mode/HOSTDOC_MODE + 함정 문서화.

하위호환

기존 5개 resolveConfig 호출부는 1-인자 형태 그대로. 추가된 2번째 인자는 optional이라 동작 무변경. mode 미지정 & 함정 아닌 경로는 경고 0건.

테스트

test/config.test.ts에 forced-mode 7종 + shadow 4종 추가(TDD, RED→GREEN). 전체 324/324 통과, build·typecheck clean, 출력 pristine. AWS creds·네트워크·Terraform 없이 통과.

참고

  • Spec: docs/superpowers/specs/2026-07-06-explicit-mode-control-design.md
  • Plan: docs/superpowers/plans/2026-07-06-explicit-mode-control.md

🤖 Generated with Claude Code

jkas2016 and others added 7 commits July 6, 2026 12:12
Adds --mode / HOSTDOC_MODE to pin the derived hosting mode (B), plus
stderr warnings when a forced mode ignores fields or when a
higher-precedence bucket is shadowed by a config domain (D). Rejects
direction C (auto precedence flip) as too surprising.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 tasks (TDD): forced-mode pin + warn injection, shadow detection,
CLI --mode wiring, docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…main (#39)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…39)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The forced-mode-from-env case ignores config domain/distribution, whose
default stderr warning leaked into test output. Inject a no-op warn; the
warning itself is asserted in dedicated cases.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jkas2016 and others added 2 commits July 6, 2026 16:27
The publish command spread `mode` into runPublish's args via overrides(),
but runPublish rebuilt the Overrides for resolveConfig inline and dropped
`mode` — so `hostdoc publish --mode s3-website` (the documented interface)
was silently ignored and still resolved via the config file's domain.
HOSTDOC_MODE env still worked because resolveConfig reads env directly.

Add `mode?: Mode` to PublishArgs and pass `mode: args.mode` to
resolveConfig. Regression test drives runPublish --dry-run with a
cloudfront ambient config and asserts --mode s3-website forces the
s3-website URL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Normalize the forced-mode value to lowercase before matching (so
S3-Website, CLOUDFRONT, SELF-HOSTED all resolve), while echoing the
user's original spelling in the invalid-mode error. Genuine typos
(e.g. s3website) still error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jkas2016
jkas2016 merged commit bc66698 into main Jul 6, 2026
3 checks passed
@jkas2016
jkas2016 deleted the feat/39-explicit-mode-control branch July 6, 2026 07:45
github-actions Bot pushed a commit that referenced this pull request Jul 11, 2026
# [1.3.0](v1.2.1...v1.3.0) (2026-07-11)

### Features

* explicit --mode / HOSTDOC_MODE + mode-derivation footgun warning ([#39](#39)) ([#48](#48)) ([bc66698](bc66698))
* self-hosted hosting mode — publish to your own NAS/PC ([#41](#41)) ([1aebec6](1aebec6))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] HOSTDOC_BUCKET env can't override a cloudfront config to s3-website mode (mode derived from domain, silently)

1 participant