Skip to content

deisign/open-source-signal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

141 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Open Source Signal

Open Source Signal / Сигнал відкритих джерел is a static publishing toolkit for a bilingual OSINT journal focused on Ukrainian accountability work.

It is built from wartime Kyiv by a Ukrainian soldier. For Ukraine, OSINT is not a hobby or a niche technical craft. It is one of the ways society documents war, resists disinformation, preserves evidence, understands attacks, and keeps public accountability alive under pressure.

The project treats OSINT as a civic skill: how to read sources, verify claims, handle evidence, explain limits, and publish without causing unnecessary harm. The editorial focus is Ukrainian accountability OSINT with an international horizon: war-crimes verification, public-interest investigations, Russian KIA/POW/MIA/missing/wounded OSINT, platform research, geolocation, surveillance infrastructure, and researcher safety.

The visible output is a bilingual digest. The larger goal is reusable open infrastructure: source-aware publishing, editorial workflows, ethical guardrails, verification notes, topic archives, weekly editions, and practical OSINT literacy for Ukrainian and international readers.

Documentation

Project rules and operational notes live in:

docs/EDITORIAL_POLICY.md
docs/SOURCE_POLICY.md
ROADMAP.md
SECURITY.md

These documents cover editorial scope, source roles, Telegram lead handling, high-risk attribution language, publication boundaries, roadmap, and security reporting.

Roadmap

The project is meant to grow beyond a daily digest into reusable public-interest OSINT infrastructure: weekly editions, evidence and source-risk metadata, topic pages, archive filters, link checking, and cautious Telegram lead collection.

See:

ROADMAP.md

What it does

The project currently supports eight working modes.

0. Create a safe draft for the next issue

create_issue.py creates an unfinished issue in drafts/ so it cannot break the published site.

python create_issue.py --date 2026-05-14 --issue 001

When the draft is filled, validate and publish it into issues/:

python create_issue.py --publish drafts/2026-05-14.json

Full instructions are in:

docs/ADD_ISSUE.md

1. Render one issue

render_issue.py takes one issue JSON file and renders a standalone HTML issue using templates/issue.html.j2.

python render_issue.py issues/2026-05-13.json --out dist

2. Build the web front page and archive

build_site.py takes all JSON files from issues/, renders issue pages into dist/issues/, and builds:

dist/index.html
dist/archive.html
dist/issues/open-source-signal-2026-05-13.html

Run:

python build_site.py --issues issues --templates templates --out dist --config site.json

3. Generate Telegram announcements

telegram_digest.py takes the same issue JSON and renders a short Telegram announcement in English or Ukrainian.

python telegram_digest.py issues/2026-05-13.json \
  --lang uk \
  --url https://osintsignal.org/issues/open-source-signal-2026-05-13.html \
  --out dist

4. Send Telegram announcements locally

send_telegram.py sends a prepared announcement to a Telegram channel or chat. The default parse mode is Telegram HTML, so generated announcements keep bold titles, italic leads, and linked full-issue URLs.

export TELEGRAM_BOT_TOKEN="123456:ABC..."
export TELEGRAM_CHAT_ID="@your_channel_name"

python send_telegram.py \
  --text-file dist/telegram-open-source-signal-2026-05-13.uk.txt \
  --disable-preview

Dry run:

python send_telegram.py \
  --text-file dist/telegram-open-source-signal-2026-05-13.uk.txt \
  --chat-id @your_channel_name \
  --dry-run

5. Build and deploy through GitHub Pages

The repository-ready GitHub Actions workflow is included:

.github/workflows/pages.yml

On every push to main, it installs dependencies, runs tests, builds dist/, uploads the Pages artifact and deploys it. Manual runs are available from the Actions tab.

Setup instructions are in:

docs/GITHUB_PAGES_SETUP.md

6. Publish Telegram announcement through GitHub Actions

A manual Telegram workflow is included:

.github/workflows/telegram.yml

Add repository secrets:

TELEGRAM_BOT_TOKEN
TELEGRAM_CHAT_ID

Then run:

Actions → Publish Telegram announcement → Run workflow

The workflow is manual on purpose, so regular rebuild commits do not spam the channel.

Setup instructions are in:

docs/TELEGRAM_SETUP.md

7. Import Daily Signal text into issue JSON

import_daily_signal.py converts a structured Daily Signal markdown/text file into a complete issues/YYYY-MM-DD.json file.

python import_daily_signal.py drafts/daily_signal_2026-05-15.md \
  --date 2026-05-15 \
  --issue 002 \
  --out issues

A manual GitHub Actions workflow is also included:

.github/workflows/import_daily_signal.yml

Use it from:

Actions → Import Daily Signal → Run workflow

Full instructions are in:

docs/IMPORT_DAILY_SIGNAL.md

8. Publish a Daily Issue with one GitHub Actions run

The combined publishing workflow is included:

.github/workflows/publish_daily_issue.yml

Use it from:

Actions → Publish Daily Issue → Run workflow

It imports a pasted Daily Signal, runs tests, builds the site, commits the issue, renders the Telegram announcement, checks duplicate protection, sends Telegram if enabled, and records the send log.

Full instructions are in:

docs/PUBLISH_DAILY_ISSUE.md

Editorial and source policy

The project now keeps editorial rules and source registries in the repository:

docs/EDITORIAL_POLICY.md
docs/SOURCE_POLICY.md
data/sources_web.yaml
data/sources_telegram.yaml

Language handling:

  • English-language OSINT material is adapted into Ukrainian.
  • Ukrainian-only material is adapted back into English for international readers.
  • Both versions must read like edited publication text, not literal machine translations.

New Ukrainian-accountability rubrics:

Ukraine Lens / Українська оптика
War Crimes Verification / Верифікація воєнних злочинів
Losses, Captivity & Missing / Втрати, полон, зниклі
Telegram Radar / Telegram-радар

Evocation.info is included as a source pointer, not as standalone proof.

Install

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Test

python -m pytest -q

Data model

The main editable issue files live in:

issues/

Each item contains both English and Ukrainian adapted text:

  • rubric / emoji / theme
  • source name, date and URL
  • what happened
  • why it matters
  • how to use it
  • limits
  • tags

Internal editorial notes are stored in internal_notes inside issue JSON, but they are not rendered on public issue pages.

Site URL

The public base URL is configured in:

site.json

Default:

https://osintsignal.org

The Telegram workflow uses this base_url when the manual issue_url input is left empty.

Typography

The HTML templates use:

  • Fraunces for the Latin masthead.
  • Source Serif 4 for Ukrainian display typography.
  • Inter for body text.
  • Arimo for rubric labels and field labels such as What happened, Why it matters, Що сталося, Чому це важливо.
  • JetBrains Mono for technical/meta elements.

Telegram duplicate protection

The manual Telegram workflow records successful sends in data/telegram_sent.json. Re-running the workflow for the same issue/language will not post again unless the force input is set to true.

About

Public-interest OSINT publishing toolkit for Ukrainian accountability, war-crimes verification, POW/MIA/losses reporting, and ethical OSINT literacy.

Topics

Resources

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors