Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/follow-banners/00-developer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/follow-banners/01-reading.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/follow-banners/02-meeting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/follow-banners/03-cafe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/follow-banners/04-travel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions assets/follow-banners/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# 太陽の固定フォローバナー

承認済みのキャラクターを使った固定アセット。毎回生成し直さず、`manifest.json` のCDN URLを記事へ埋め込む。原本PNGと生成プロンプトもこのフォルダに保存する。

## 選択規則

- ランダム候補は `01-reading`(読書)、`02-meeting`(打ち合わせ)、`03-cafe`(カフェ)、`04-travel`(旅行)の4枚。
- `00-developer` は採用済み原本として保管するが、現在の抽選対象には含めない。
- 新規記事ごとに4枚から等確率で1枚選ぶ。同じ画像の連続選択は許容し、テーマによる選別や順番交代に置き換えない。
- 選択した画像IDとURLを記事の `post_id` とともに実行記録へ残す。再試行時はその記録を再利用し、引き直さない。
- 同じ記事内では同じバナーを使う。公開ページの閲覧ごとに切り替える機能ではない。
- 下記の抽選例は新規記事用。既存記事は記録済みの選択を使う。乱数実行機能が使えない環境では、その制約を報告し実行済みと偽らない。

```python
import json
import secrets
from pathlib import Path

manifest = json.loads(Path("assets/follow-banners/manifest.json").read_text())
selected_id = secrets.choice(manifest["candidates"])
selected = next(a for a in manifest["assets"] if a["id"] == selected_id)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Crash Risk: The next() function will raise StopIteration if no matching asset ID is found in the manifest. Add a default value or error handling to prevent runtime crashes when the manifest is corrupted or candidates list is out of sync with assets.

Suggested change
selected = next(a for a in manifest["assets"] if a["id"] == selected_id)
selected = next((a for a in manifest["assets"] if a["id"] == selected_id), None)
if selected is None:
raise ValueError(f"Selected ID '{selected_id}' not found in assets")
print(selected["id"], selected["url"])

print(selected["id"], selected["url"])
```

## 配置

記事の導入直後に画像を入れ、直下と記事末尾へ `[Xでフォローする](https://x.com/taiyo_ai_gakuse)` を置く。画像内の文字自体はリンクではない。リンクを太字記法で包まない(変換崩れ防止)。本人Substackの購読リンクは別途維持する。

サムネイルや本文図解とは別のアセットであり、記事のカバーには設定しない。公開前に画像URLとフォロー先が正しく保存されていることを確認する。CDNが取得できない場合は、無断で再生成せず下書きと不足理由を残す。

## 週次タスク

[開発系の長文記事を毎週自動公開する](https://chatgpt.com/scheduled/6aac992cd23481919cc55729e0e837d6) の指示に4枚のURLと選択・再試行規則を直接保存する。クラウド実行でローカルファイルが読めることを前提にしない。タスクの実行日時、メール配信設定、他のタスクは変更しない。

## 手動検証(TC-001 / Issue #12)

1. 5枚のPNGが読み込めること、1983×793であること、SHA256がマニフェストと一致することを確認する。
2. ランダム候補が4枚のみで重複しないことを確認する。
3. 4枚のCDN URLが200かつ画像として読み込めることを確認する。
4. 抽選例の実行結果が候補内であることを確認する(短い試行の出現頻度から等確率性を証明しない)。
5. 週次タスクを保存後に開き直し、4枚のURLと一度だけ選択する規則が残っていることを確認する。

画像の人物・文字・場面は生成後に目視確認済み。生成方法はbuilt-in image_gen。元写真や認証情報はこのリポジトリに含めない。
11 changes: 11 additions & 0 deletions assets/follow-banners/generation-prompts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"generator": "built-in image_gen",
"reference": "採用済みの開発版キャラクターバナー",
"prompts": [
"Create a new 5:2 landscape Japanese follow banner in exactly the illustrated visual language of the provided approved banner. Preserve the SAME character identity: youthful adult man, black center-parted ear-length hair, rounded face, black T-shirt, same eyes and facial proportions. Precise dark navy outlines, flat muted color planes, light paper texture, one cel shadow tone, character warmth with business editorial restraint. No photorealism, no chibi, no exaggerated anime eyes. LEFT 53% is warm ivory whitespace with exact same large dark navy Japanese CTA in two lines: 'フォロー' and 'してください。', a short muted teal underline; no other text anywhere. RIGHT 47% contains the character and a tasteful uncluttered scene. No logos, signatures, labels, speech bubbles. Match composition and text legibility to reference. Change scene as follows: READING AND LEARNING: seated in a comfortable pale sage armchair, holding an open navy hardcover book with both hands, looking up toward viewer with a thoughtful soft smile. A small side table with two closed books, faint bookcase in background. Muted sage, cream and warm wood. No laptop, no microphone.",
"Create a new 5:2 landscape Japanese follow banner in exactly the illustrated visual language of the provided approved banner. Preserve the SAME character identity: youthful adult man, black center-parted ear-length hair, rounded face, black T-shirt, same eyes and facial proportions. Precise dark navy outlines, flat muted color planes, light paper texture, one cel shadow tone, character warmth with business editorial restraint. No photorealism, no chibi, no exaggerated anime eyes. LEFT 53% is warm ivory whitespace with exact same large dark navy Japanese CTA in two lines: 'フォロー' and 'してください。', a short muted teal underline; no other text anywhere. RIGHT 47% contains the character and a tasteful uncluttered scene. No logos, signatures, labels, speech bubbles. Match composition and text legibility to reference. Change scene as follows: CONVERSATION AND MEETING: seated at a small meeting table, leaning forward slightly with an approachable engaged smile and one hand gently open while explaining, other hand resting beside a simple notebook and pen. Show only main character, imply listener outside image. Pale blue-gray wall with two minimal geometric panels. Restrained teal and warm sand palette. No computer, no microphone, no text in notebook.",
"Create a new 5:2 landscape Japanese follow banner in exactly the illustrated visual language of the provided approved banner. Preserve the SAME character identity: youthful adult man, black center-parted ear-length hair, rounded face, black T-shirt, same eyes and facial proportions. Precise dark navy outlines, flat muted color planes, light paper texture, one cel shadow tone, character warmth with business editorial restraint. No photorealism, no chibi, no exaggerated anime eyes. LEFT 53% is warm ivory whitespace with exact same large dark navy Japanese CTA in two lines: 'フォロー' and 'してください。', a short muted teal underline; no other text anywhere. RIGHT 47% contains the character and a tasteful uncluttered scene. No logos, signatures, labels, speech bubbles. Match composition and text legibility to reference. Change scene as follows: CAFE BREAK: sitting beside a cafe window, holding a plain ceramic terracotta coffee cup, relaxed friendly closed-mouth smile. Black T-shirt same as reference. Window with soft abstract greenery and sunlight, simple light wooden table, small plate. Muted warm beige and dusty blue, tranquil polished everyday scene. No laptop, no microphone.",
"Create a new 5:2 landscape Japanese follow banner in exactly the illustrated visual language of the provided approved banner. Preserve the SAME character identity: youthful adult man, black center-parted ear-length hair, rounded face, black T-shirt, same eyes and facial proportions. Precise dark navy outlines, flat muted color planes, light paper texture, one cel shadow tone, character warmth with business editorial restraint. No photorealism, no chibi, no exaggerated anime eyes. LEFT 53% is warm ivory whitespace with exact same large dark navy Japanese CTA in two lines: 'フォロー' and 'してください。', a short muted teal underline; no other text anywhere. RIGHT 47% contains the character and a tasteful uncluttered scene. No logos, signatures, labels, speech bubbles. Match composition and text legibility to reference. Change scene as follows: TRAVEL AND CITY WALK: three-quarter waist-up character outdoors, black T-shirt with a simple slate-blue backpack on both shoulders, holding a small folded unlabelled paper map, looking toward viewer with an inviting smile. In background a restrained simplified street corner with warm buildings and a small tree, no signs or lettering. Muted blue, ivory and terracotta, clean spacious scene. No computer, no microphone."
],
"developerPrompt": "Use the provided banner as character identity reference. Create a new Japanese follow banner 5:2 landscape featuring exactly the SAME young male character: center-parted ear-length black hair, distinctive youthful rounded face, black T-shirt. Clearly an illustrated character with slightly enlarged head, simple expressive facial features, NOT photorealistic, NOT a generic anime face. Refined Japanese editorial cartoon aesthetic: precise slightly grainy dark colored outlines, thoughtfully organized geometric flat color shapes, limited cel shadows, tasteful print texture, convincing carefully drawn everyday objects, harmonious composition mixing graphic design clarity with manga character warmth. Keep business-professional restraint, generous whitespace, no loud comic effects, no exaggerated chibi proportions, no sparkles or stickers. LEFT area contains only exact Japanese CTA on two lines 'フォロー' and 'してください。' in large clean dark navy sans-serif. No other text, logos, watermark or signatures. RIGHT area character. Variant B: pale cool blue background with ivory negative space for text and a restrained burnt-orange accent in a small desk object. Character seated at a minimal pale wood desk working on a slim dark laptop, looking up toward viewer with warm friendly smile. A small notebook and mug neatly arranged, accurately drawn perspective, uncluttered business workspace vignette contained in right half. Same black T-shirt and same recognizable hairstyle and face as reference. Clear character silhouette, thoughtful everyday storytelling without crowding."
}
58 changes: 58 additions & 0 deletions assets/follow-banners/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"version": 1,
"follow_url": "https://x.com/taiyo_ai_gakuse",
"selection": "uniform_random_per_article",
"candidates": [
"01-reading",
"02-meeting",
"03-cafe",
"04-travel"
],
Comment on lines +5 to +10

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛑 Logic Error: The candidates array contains 4 IDs but the assets array has 5 items. If this manifest is used programmatically without cross-validation, there's a mismatch risk. The code in README.md line 21 could fail if a candidate ID doesn't exist in assets, or if asset indexing logic assumes array positions match.

"assets": [
{
"id": "00-developer",
"file": "00-developer.png",
"width": 1983,
"height": 793,
"sha256": "aa580666fe2062a0883d384019784127b551a59d5a96ca61588e8d5e1f2d3860",
"url": "https://substack-post-media.s3.amazonaws.com/public/images/34221615-a306-4468-b6c7-73fe320775bd_1983x793.jpeg",
"random_candidate": false
},
{
"id": "01-reading",
"file": "01-reading.png",
"width": 1983,
"height": 793,
"sha256": "7f02aad3eb1be31918117b36df3f3184a9f34490a4dcaa6f378d9f35c3affcb1",
"url": "https://substack-post-media.s3.amazonaws.com/public/images/c2287c0f-d4fe-4ec9-af43-e0000666d145_1983x793.jpeg",
"random_candidate": true
},
{
"id": "02-meeting",
"file": "02-meeting.png",
"width": 1983,
"height": 793,
"sha256": "1548c09e49820213919cd3a088d9c819c2141e6a3cba915b1451900aed1d82fe",
"url": "https://substack-post-media.s3.amazonaws.com/public/images/6fab0705-e981-47f6-887e-1d6b22575a7f_1983x793.jpeg",
"random_candidate": true
},
{
"id": "03-cafe",
"file": "03-cafe.png",
"width": 1983,
"height": 793,
"sha256": "41343c01703370e3b3bde5574e9326aefcc9877f4b791785b942b873d6885da7",
"url": "https://substack-post-media.s3.amazonaws.com/public/images/e955e5d5-0bef-4df3-959a-bf26c6d017c2_1983x793.jpeg",
"random_candidate": true
},
{
"id": "04-travel",
"file": "04-travel.png",
"width": 1983,
"height": 793,
"sha256": "146d8a65d513c1b5ffb09a5909d6ed0aa20d94921764ab934640d9653ef4adfa",
"url": "https://substack-post-media.s3.amazonaws.com/public/images/6f586863-569b-4845-b44b-441e67f1cd6a_1983x793.jpeg",
"random_candidate": true
}
]
}
1 change: 1 addition & 0 deletions skills/substack-article/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Claude Code から作成・投稿するためのものです。画像生成は C

## 関連ドキュメント

- 太陽本人のフォロー導線には `../../assets/follow-banners/README.md` と `manifest.json` の固定画像を使う。記事ごとに読書・打ち合わせ・カフェ・旅行の4枚から1枚をランダム選択し、同じ記事の再試行では再選択しない。バナーを毎回生成し直さない。
- `templates/best-practices.md` — Substack 運用フレームワーク・推奨設定・成長戦略の要点(執筆や設定判断時に参照)
- `templates/thumbnail-prompt.md` — サムネ生成(Codex 経由)の Prompt テンプレ
- `templates/notes-workflow.md` — Notes(短文)の投稿パターン・運用ルール
Expand Down
17 changes: 17 additions & 0 deletions test-board.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: 1
project:
name: substack-mcp
repo: nanameru/substack-mcp
source_roots: [assets, skills]
cases:
- id: TC-001
title: "固定フォローバナー: 4枚の画像と選択設定を検証する"
feature: "固定フォローバナー"
scenario: "4枚の画像と選択設定を検証する"
status: done
priority: medium
type: manual
source: [assets/follow-banners]
test_file: ""
issues: [12]
notes: "2026-09-18 手動検証済み。assets/follow-banners/README.md の検証手順に従いPNG5枚の寸法・SHA256・読み込み、候補4件、CDN4件のHTTP 200とJPEG読込を確認。新規記事の抽選例は03-cafe。週次指示を保存後に再取得し完全一致を確認。自動投稿の次回実行そのものは未実施。"