Skip to content

docs: add multilingual deployment guides - #90

Merged
IceCodeNew merged 5 commits into
masterfrom
codex/localize-readme
Jul 22, 2026
Merged

docs: add multilingual deployment guides#90
IceCodeNew merged 5 commits into
masterfrom
codex/localize-readme

Conversation

@IceCodeNew

@IceCodeNew IceCodeNew commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • make English the default README while preserving Simplified Chinese and adding Japanese documentation
  • document JMA forecast office codes and add a public Tokyo location example
  • reorganize the environment template and have the Docker startup command pass BRIEFING_TIMEZONE to the container as TZ

Validation

  • prek run --all-files
  • uv run --with pytest --with pytest-cov -- pytest --cov --cov-branch --cov-report=xml (868 passed)
  • coverage compared with master: line 99.85% -> 99.85%, branch 99.54% -> 99.54%

Summary by CodeRabbit

  • Documentation
    • Added Japanese and Simplified Chinese user guides covering setup, deployment, configuration, scheduling, and troubleshooting.
    • Expanded English documentation with clearer Docker, location, model, publishing, diagnostics, and data-source guidance.
    • Added a multilingual reference for JMA office codes and instructions for configuring them.
  • Configuration
    • Improved environment-variable documentation and organization without changing available settings.
    • Added a sample Kasumigaseki location configuration.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@IceCodeNew, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 118ecfdd-30b3-4e4c-ad20-b9ecc1056bf2

📥 Commits

Reviewing files that changed from the base of the PR and between 12a5523 and a074913.

📒 Files selected for processing (4)
  • README.md
  • README_ja.md
  • README_zh-Hans.md
  • env.example
📝 Walkthrough

Walkthrough

The PR expands deployment and operational documentation in English, Japanese, and Simplified Chinese, reorganizes environment configuration guidance, adds a Kasumigaseki location example, and documents JMA office codes.

Changes

Documentation and configuration

Layer / File(s) Summary
English README guidance
README.md
Rewrites core setup, Docker usage, location and publisher configuration, troubleshooting, diagnostics, and data-source documentation in English.
Localized deployment and operations guides
README_ja.md, README_zh-Hans.md
Adds Japanese and Simplified Chinese deployment, configuration, RSS, execution, and troubleshooting guides.
Configuration and location examples
env.example, locations.example.json
Reorganizes environment-variable guidance and adds a Kasumigaseki location example.
JMA office code reference
docs/jma-office-codes.md
Adds multilingual JMA office-code listings and usage instructions for locations.json.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: 🕐 20-40 Minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding multilingual deployment documentation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/localize-readme

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@IceCodeNew
IceCodeNew marked this pull request as ready for review July 22, 2026 04:32
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Docs: add multilingual READMEs, JMA office code guide, and TZ startup notes

📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Make English the default README and add Japanese + Simplified Chinese guides.
• Document JMA forecast office codes and add a Tokyo (Kasumigaseki) location example.
• Reorganize env.example and align Docker container TZ with BRIEFING_TIMEZONE.
Diagram

graph TD
U[User] --> R["README (EN/JA/ZH)"] --> D["Docker run (TZ from .env)"] --> C[Container] --> A["Weather Briefing"]
R --> E["env.example"] --> D
R --> L["locations.example.json"] --> J["jma_office_code"] --> A
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Move deployment guides to docs/ and keep README minimal
  • ➕ Reduces README length and makes future additions easier to structure
  • ➕ Encourages deeper topic-based docs (deployment, providers, locations)
  • ➖ Adds one more click for first-time users
  • ➖ Requires careful navigation/TOC to avoid discoverability regressions
2. Use a docs site generator (e.g., MkDocs/Docusaurus) for i18n
  • ➕ Better navigation/search and first-class localization workflows
  • ➕ Scales better as more guides/providers are added
  • ➖ Introduces new build/deploy surface area and maintenance overhead
  • ➖ Overkill if the project intentionally stays lightweight

Recommendation: Keep the current approach (separate localized READMEs with a language switcher) because it’s the lowest-overhead way to provide multilingual onboarding in GitHub. Consider a docs-site migration only if documentation continues to expand significantly.

Files changed (6) +533 / -104

Documentation (5) +484 / -62
README.mdMake English README default and expand deployment/location guidance +73/-62

Make English README default and expand deployment/location guidance

• Replaces the prior Chinese-first README with an English default while adding a language switcher. Improves Docker run instructions by passing TZ derived from BRIEFING_TIMEZONE, and adds clearer location configuration guidance including JMA office code references.

README.md

README_ja.mdAdd Japanese deployment and configuration guide +164/-0

Add Japanese deployment and configuration guide

• Introduces a full Japanese README covering prerequisites, Docker deployment, location/model configuration, and troubleshooting. Includes guidance for Japan usage (Asia/Tokyo timezone and JMA office codes).

README_ja.md

README_zh-Hans.mdAdd Simplified Chinese README as a dedicated localized document +163/-0

Add Simplified Chinese README as a dedicated localized document

• Adds a full zh-Hans README parallel to the English/Japanese guides. Includes Docker deployment, location configuration (including JMA office codes), and troubleshooting guidance.

README_zh-Hans.md

jma-office-codes.mdDocument JMA forecast office codes and how to configure them +76/-0

Document JMA forecast office codes and how to configure them

• Adds a trilingual (JA/EN/ZH) table of JMA office codes for all 47 prefectures and explains how to set jma_office_code in locations.json. Links the canonical JMA area.json source.

docs/jma-office-codes.md

locations.example.jsonAdd Tokyo (Kasumigaseki) Japanese example with JMA office code +8/-0

Add Tokyo (Kasumigaseki) Japanese example with JMA office code

• Extends the example locations list with a public Tokyo location configured for Japanese output and JMA augmentation via jma_office_code=130000.

locations.example.json

Other (1) +49 / -42
env.exampleReorganize env template and clarify publisher/timezone/reliability settings +49/-42

Reorganize env template and clarify publisher/timezone/reliability settings

• Reorders and expands comments to make initial setup clearer (publisher selection, Telegram credentials, token limits, timezone notes). Groups geocoding/state/RSS/reliability settings more explicitly and notes that Docker startup should pass BRIEFING_TIMEZONE as TZ.

env.example

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@env.example`:
- Around line 23-24: Update the comment above LLM_MAX_OUTPUT_TOKENS to remove
the direct token-versus-character comparison and document the intended
relationship using a meaningful, tested conversion or validation rule; preserve
the existing configuration values.
- Around line 36-38: Make provider-resolution documentation consistent across
env.example, README.md, README_ja.md, and README_zh-Hans.md: document the
Singapore/NEA and Japan/JMA automatic provider additions, or explicitly state
that setting WEATHER_PROVIDERS overrides and disables those regional defaults.
Ensure all regional examples describe the actual provider-resolution behavior
and preserve the intended default behavior when WEATHER_PROVIDERS is omitted.

In `@README_ja.md`:
- Line 133: Replace the shell comment “将来の日付の予報を確認” in the README guide with
equivalent natural Japanese wording, preserving the comment’s meaning and
surrounding instructions.
- Line 26: Update the QWeather reference in the README sentence to use the
provider’s official product name consistently, replacing the generic localized
phrase while preserving the existing credential and JWT documentation details.

In `@README.md`:
- Around line 50-51: Replace the recursive UID/GID ownership and mode-600
commands at README.md lines 50-51 with a shared group/ACL or equivalent
container-readable permissions strategy that preserves host operator access;
apply the same correction at README_ja.md lines 50-51 and README_zh-Hans.md
lines 50-51.
- Around line 111-121: Harden the copied private RSS file before it is mounted
by adding explicit restrictive permissions and ownership/read-access setup in
the Docker instructions. Apply the same guidance at README.md lines 111-121,
README_ja.md lines 111-121, and README_zh-Hans.md lines 111-121, preserving the
existing mount command and ensuring the file is readable by the container user
without permissive access.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b6577218-2b89-4c93-a251-c8d7ab7504c1

📥 Commits

Reviewing files that changed from the base of the PR and between db5b0ac and 12a5523.

📒 Files selected for processing (6)
  • README.md
  • README_ja.md
  • README_zh-Hans.md
  • docs/jma-office-codes.md
  • env.example
  • locations.example.json

Comment thread env.example Outdated
Comment thread env.example Outdated
Comment thread README_ja.md Outdated
Comment thread README_ja.md Outdated
Comment thread README.md Outdated
Comment thread README.md
@qodo-code-review

qodo-code-review Bot commented Jul 22, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 41 rules

Grey Divider


Remediation recommended

1. Secrets group-readable in docs ✗ Dismissed 🐞 Bug ⛨ Security
Description
The README Docker deployment steps set ${ROOT_DIR}/.env (and all ${ROOT_DIR}/*.json) to mode
640 after chgrp 65532, making credentials readable by any host principal in group 65532. Since
.env contains Telegram/LLM secrets, this is a confidentiality regression on shared hosts or hosts
where GID 65532 is reused.
Code

README.md[R50-53]

+sudo chgrp -R 65532 "${ROOT_DIR}"
+chmod 750 "${ROOT_DIR}"
+chmod 770 "${ROOT_DIR}/state"
+chmod 640 "${ROOT_DIR}/.env" "${ROOT_DIR}"/*.json
Relevance

⭐⭐⭐ High

Prior README deployment used chmod 600 for .env/*.json (PR #40, #81); team also fixed sensitive
logging (PR #55).

PR-#40
PR-#81
PR-#55

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The README explicitly makes .env and JSON files group-readable, and env.example shows that
.env includes Telegram credentials; thus the documented permissions can expose secrets to host
principals in that group.

README.md[49-53]
README.md[116-120]
env.example[16-22]
README_ja.md[49-53]
README_zh-Hans.md[49-53]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
README Docker instructions make `.env` (and `*.json`) group-readable (`chmod 640` after `chgrp 65532`). Because `.env` contains credentials, this can leak secrets to any host user/process that has GID 65532.

## Issue Context
- The docs use bind mounts and run the container as a non-root user, so the container still needs read access to config files.
- The current instructions achieve that by granting group read, but this widens the host-side trust boundary.

## Fix Focus Areas
- README.md[49-53]
- README.md[116-120]
- README_ja.md[49-53]
- README_zh-Hans.md[49-53]
- env.example[16-22]

## Suggested fix
Update the deployment snippets to keep secrets non-group-readable while still letting the container read them. For example, document one of these approaches:
1) `chown` the secret files to UID/GID 65532 and keep `chmod 600` (most secure, but requires editing with sudo), or
2) keep ownership with the operator but use an ACL to grant UID/GID 65532 read access (e.g., `setfacl`), or
3) use Docker secrets / a dedicated host group (not a globally reused GID) and keep `.env` at `600`.

Ensure the same change is applied consistently across English/Japanese/Chinese READMEs, and consider calling out that `rss-sources.json` may contain private URLs and should be protected similarly.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. kasumigaseki real location data ✓ Resolved 📘 Rule violation ⛨ Security
Description
locations.example.json adds a specific real-world address and GPS coordinates for kasumigaseki
without clearly labeling it as a public/example location. This risks committing private runtime data
or overly precise real-world identifiers into the repo.
Code

locations.example.json[R10-15]

+    "id": "kasumigaseki",
+    "name": "東京都千代田区霞が関",
+    "language": "ja",
+    "jma_office_code": "130000",
+    "latitude": 35.6738,
+    "longitude": 139.7524
Relevance

⭐⭐⭐ High

Team previously accepted removing realistic lat/long from repo test data; likely to flag precise
real coords in examples too.

PR-#80
PR-#89

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 2141693 prohibits committing precise real-world addresses or GPS coordinates unless
they are clearly documented as public examples. The added kasumigaseki entry includes an explicit
address string and latitude/longitude values in a committed example file without any clear labeling
in the file itself.

Rule 2141693: Disallow hard-coded secrets and private runtime data in committed code and tests
locations.example.json[10-15]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new sample location (`kasumigaseki`) includes a specific real-world address and fairly precise coordinates, but it is not clearly documented as a public/example value.

## Issue Context
The compliance rule disallows committing precise real-world addresses/coordinates unless they are clearly documented as public examples.

## Fix Focus Areas
- locations.example.json[10-15]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Fragile TZ extraction ✓ Resolved 🐞 Bug ◔ Observability
Description
The README Docker command derives TZ via sed from .env and unconditionally passes it to
docker run, which can override the image default (TZ=Asia/Shanghai) with an
empty/invalid/multiline value when BRIEFING_TIMEZONE is missing/duplicated or the file uses
CRLF/quotes. This can skew container-local time (e.g., log timestamps) even though scheduling uses
BRIEFING_TIMEZONE directly.
Code

README.md[R54-61]

+TZ="$(sed -n 's/^BRIEFING_TIMEZONE=//p' "${ROOT_DIR}/.env")"
+
docker pull "${IMAGE}"
docker run -d \
  --name weather-briefing \
  --restart unless-stopped \
+  --env "TZ=${TZ}" \
  --env-file "${ROOT_DIR}/.env" \
Relevance

⭐⭐ Medium

README Docker command tweaks often accepted, but no prior review evidence about validating TZ
extraction/empty override.

PR-#81
PR-#40

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
README now computes TZ by sed and injects it into the container; because Dockerfile already sets
TZ=Asia/Shanghai, passing an empty/invalid extracted value overrides that default. The app
independently defaults BRIEFING_TIMEZONE and strips whitespace/quotes in _clean_env, but the
README extraction does not, and logging timestamps are formatted using local time.

README.md[49-66]
README_ja.md[49-66]
README_zh-Hans.md[49-66]
Dockerfile[35-38]
weather_briefing/config.py[41-47]
weather_briefing/config.py[416-419]
weather_briefing/cli.py[241-244]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Docker startup snippet parses `BRIEFING_TIMEZONE` from `.env` using `sed` and always injects it as `TZ`. If the extraction yields empty/invalid/multiline output (missing key, duplicates, CRLF, or quoted value), it overrides the image’s default `TZ` and can cause incorrect container-local timestamps.

### Issue Context
- The image already sets a sane default `TZ=Asia/Shanghai`.
- The application scheduler uses `BRIEFING_TIMEZONE` (separately) and strips whitespace/quotes in config parsing, but the README’s `sed` parsing does not.

### Fix Focus Areas
- README.md[49-66]
- README_ja.md[49-66]
- README_zh-Hans.md[49-66]

### Suggested fix (docs)
Update the snippet to (a) pick a single value, (b) strip `\r`, and (c) default to `Asia/Shanghai` when missing, e.g.:

```sh
TZ="$(sed -n 's/^BRIEFING_TIMEZONE=//p' "${ROOT_DIR}/.env" | tail -n 1 | tr -d '\r')"
TZ="${TZ:-Asia/Shanghai}"

# ... then:
# --env "TZ=${TZ}" \
```

Optionally, only pass `--env TZ=...` when `TZ` is non-empty to avoid overriding the Dockerfile default.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

4. Language fallback undocumented ✓ Resolved 🐞 Bug ≡ Correctness ⭐ New
Description
The README says location language only supports en, ja, zh-CN, and zh-TW, but the app
accepts any basic BCP47-like tag (e.g. ja-jp normalizes to ja-JP) and passes it through to the
LLM as output_language while rendering section labels via a closest-supported-language fallback.
This can make configs appear “unsupported” even when they work (e.g. ja-JP), and can also cause
label-language fallback (e.g. to English) if a non-localized language tag is configured.
Code

README.md[81]

+`language` controls the briefing language for that location. Supported values are `en` (default), `ja`, `zh-CN`, and `zh-TW`. For locations in Japan that require JMA forecasts, also provide the local six-digit `jma_office_code`.
Relevance

⭐⭐⭐ High

Team often updates docs to match runtime behavior; similar doc/runtime mismatches were accepted in
PRs #81 and #82.

PR-#81
PR-#82

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
README.md claims a fixed set of supported values, but the runtime accepts/normalizes broader tags
(verified by tests) and then uses a closest-supported-language match for localization labels while
still passing the configured tag through to the LLM payload.

README.md[74-82]
tests/test_config.py[241-256]
weather_briefing/languages.py[12-18]
weather_briefing/service.py[631-635]
weather_briefing/render.py[21-27]
weather_briefing/render.py[208-211]
weather_briefing/reference_data.py[67-67]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The docs currently list `language` as supporting only `en`, `ja`, `zh-CN`, and `zh-TW`, but runtime behavior accepts broader BCP47-like tags (e.g. `ja-JP`) and uses fallback matching for localized labels. This mismatch can confuse operators and hide the actual fallback behavior.

## Issue Context
- Config parsing normalizes/accepts BCP47-like tags.
- The LLM receives the configured (normalized) tag as `output_language`.
- UI/section labels are only localized for `{en, ja, zh-CN, zh-TW}` and are selected using closest-match fallback.

## Fix Focus Areas
- README.md[72-82]
- README_ja.md[74-83]
- README_zh-Hans.md[74-83]

Suggested doc wording direction:
- Keep the list as the *localized* / officially supported output languages.
- Add one sentence explaining that BCP47 variants are accepted and normalized (e.g. `ja-JP` -> treated as `ja` for labels), while unsupported primaries may fall back to English labels.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Previous review results

Review updated until commit a074913

Results up to commit 12a5523 ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. kasumigaseki real location data ✓ Resolved 📘 Rule violation ⛨ Security
Description
locations.example.json adds a specific real-world address and GPS coordinates for kasumigaseki
without clearly labeling it as a public/example location. This risks committing private runtime data
or overly precise real-world identifiers into the repo.
Code

locations.example.json[R10-15]

+    "id": "kasumigaseki",
+    "name": "東京都千代田区霞が関",
+    "language": "ja",
+    "jma_office_code": "130000",
+    "latitude": 35.6738,
+    "longitude": 139.7524
Relevance

⭐⭐⭐ High

Team previously accepted removing realistic lat/long from repo test data; likely to flag precise
real coords in examples too.

PR-#80
PR-#89

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 2141693 prohibits committing precise real-world addresses or GPS coordinates unless
they are clearly documented as public examples. The added kasumigaseki entry includes an explicit
address string and latitude/longitude values in a committed example file without any clear labeling
in the file itself.

Rule 2141693: Disallow hard-coded secrets and private runtime data in committed code and tests
locations.example.json[10-15]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new sample location (`kasumigaseki`) includes a specific real-world address and fairly precise coordinates, but it is not clearly documented as a public/example value.

## Issue Context
The compliance rule disallows committing precise real-world addresses/coordinates unless they are clearly documented as public examples.

## Fix Focus Areas
- locations.example.json[10-15]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Fragile TZ extraction ✓ Resolved 🐞 Bug ◔ Observability
Description
The README Docker command derives TZ via sed from .env and unconditionally passes it to
docker run, which can override the image default (TZ=Asia/Shanghai) with an
empty/invalid/multiline value when BRIEFING_TIMEZONE is missing/duplicated or the file uses
CRLF/quotes. This can skew container-local time (e.g., log timestamps) even though scheduling uses
BRIEFING_TIMEZONE directly.
Code

README.md[R54-61]

+TZ="$(sed -n 's/^BRIEFING_TIMEZONE=//p' "${ROOT_DIR}/.env")"
+
docker pull "${IMAGE}"
docker run -d \
  --name weather-briefing \
  --restart unless-stopped \
+  --env "TZ=${TZ}" \
  --env-file "${ROOT_DIR}/.env" \
Relevance

⭐⭐ Medium

README Docker command tweaks often accepted, but no prior review evidence about validating TZ
extraction/empty override.

PR-#81
PR-#40

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
README now computes TZ by sed and injects it into the container; because Dockerfile already sets
TZ=Asia/Shanghai, passing an empty/invalid extracted value overrides that default. The app
independently defaults BRIEFING_TIMEZONE and strips whitespace/quotes in _clean_env, but the
README extraction does not, and logging timestamps are formatted using local time.

README.md[49-66]
README_ja.md[49-66]
README_zh-Hans.md[49-66]
Dockerfile[35-38]
weather_briefing/config.py[41-47]
weather_briefing/config.py[416-419]
weather_briefing/cli.py[241-244]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Docker startup snippet parses `BRIEFING_TIMEZONE` from `.env` using `sed` and always injects it as `TZ`. If the extraction yields empty/invalid/multiline output (missing key, duplicates, CRLF, or quoted value), it overrides the image’s default `TZ` and can cause incorrect container-local timestamps.

### Issue Context
- The image already sets a sane default `TZ=Asia/Shanghai`.
- The application scheduler uses `BRIEFING_TIMEZONE` (separately) and strips whitespace/quotes in config parsing, but the README’s `sed` parsing does not.

### Fix Focus Areas
- README.md[49-66]
- README_ja.md[49-66]
- README_zh-Hans.md[49-66]

### Suggested fix (docs)
Update the snippet to (a) pick a single value, (b) strip `\r`, and (c) default to `Asia/Shanghai` when missing, e.g.:

```sh
TZ="$(sed -n 's/^BRIEFING_TIMEZONE=//p' "${ROOT_DIR}/.env" | tail -n 1 | tr -d '\r')"
TZ="${TZ:-Asia/Shanghai}"

# ... then:
# --env "TZ=${TZ}" \
```

Optionally, only pass `--env TZ=...` when `TZ` is non-empty to avoid overriding the Dockerfile default.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit ad8be4e ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Secrets group-readable in docs ✗ Dismissed 🐞 Bug ⛨ Security
Description
The README Docker deployment steps set ${ROOT_DIR}/.env (and all ${ROOT_DIR}/*.json) to mode
640 after chgrp 65532, making credentials readable by any host principal in group 65532. Since
.env contains Telegram/LLM secrets, this is a confidentiality regression on shared hosts or hosts
where GID 65532 is reused.
Code

README.md[R50-53]

+sudo chgrp -R 65532 "${ROOT_DIR}"
+chmod 750 "${ROOT_DIR}"
+chmod 770 "${ROOT_DIR}/state"
+chmod 640 "${ROOT_DIR}/.env" "${ROOT_DIR}"/*.json
Relevance

⭐⭐⭐ High

Prior README deployment used chmod 600 for .env/*.json (PR #40, #81); team also fixed sensitive
logging (PR #55).

PR-#40
PR-#81
PR-#55

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The README explicitly makes .env and JSON files group-readable, and env.example shows that
.env includes Telegram credentials; thus the documented permissions can expose secrets to host
principals in that group.

README.md[49-53]
README.md[116-120]
env.example[16-22]
README_ja.md[49-53]
README_zh-Hans.md[49-53]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
README Docker instructions make `.env` (and `*.json`) group-readable (`chmod 640` after `chgrp 65532`). Because `.env` contains credentials, this can leak secrets to any host user/process that has GID 65532.

## Issue Context
- The docs use bind mounts and run the container as a non-root user, so the container still needs read access to config files.
- The current instructions achieve that by granting group read, but this widens the host-side trust boundary.

## Fix Focus Areas
- README.md[49-53]
- README.md[116-120]
- README_ja.md[49-53]
- README_zh-Hans.md[49-53]
- env.example[16-22]

## Suggested fix
Update the deployment snippets to keep secrets non-group-readable while still letting the container read them. For example, document one of these approaches:
1) `chown` the secret files to UID/GID 65532 and keep `chmod 600` (most secure, but requires editing with sudo), or
2) keep ownership with the operator but use an ACL to grant UID/GID 65532 read access (e.g., `setfacl`), or
3) use Docker secrets / a dedicated host group (not a globally reused GID) and keep `.env` at `600`.

Ensure the same change is applied consistently across English/Japanese/Chinese READMEs, and consider calling out that `rss-sources.json` may contain private URLs and should be protected similarly.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Qodo Logo

Comment thread locations.example.json
Comment thread README.md Outdated
@IceCodeNew

Copy link
Copy Markdown
Owner Author

/review

@IceCodeNew

Copy link
Copy Markdown
Owner Author

Addressed all eight CodeRabbit and Qodo findings in ad8be4e:

  • replaced the token/character comparison with provider-truncation guidance
  • documented regional provider defaults and explicit override behavior
  • corrected QWeather naming and Japanese command wording
  • preserved host ownership while granting container group access, including the private RSS file
  • removed the precise Kasumigaseki address and coordinates from the public example
  • made TZ extraction select one CRLF-safe value and retain the image default when missing

Validation: 868 tests passed with branch coverage; line coverage remains 99.85% and branch coverage remains 99.54%, matching master. All prek run --all-files hooks passed.

Comment thread README.md
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit ad8be4e

@IceCodeNew

Copy link
Copy Markdown
Owner Author

Follow-up product decisions in 57ce99f supersede the corresponding points in the previous review summary:

  • retained the Kasumigaseki entry as an intentional public configuration example
  • kept host ownership and granted both owner and the trusted container service GID 65532 write access, using find to apply 770 to directories and 660 to files; the guides now explicitly prohibit assigning unrelated host users to that group
  • moved the missing-TZ fallback into the docker run argument as TZ=${TZ:-Asia/Shanghai}

The Japanese command comment is now 指定日の天気予報を確認. Validation remains 868 passing tests, unchanged branch coverage, and all repository hooks passing.

@IceCodeNew

Copy link
Copy Markdown
Owner Author

/review

@IceCodeNew

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Comment thread README.md Outdated
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 57ce99f

@IceCodeNew

Copy link
Copy Markdown
Owner Author

/review

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit a074913

@IceCodeNew
IceCodeNew merged commit 2f82aec into master Jul 22, 2026
4 checks passed
@IceCodeNew
IceCodeNew deleted the codex/localize-readme branch July 22, 2026 05:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant