77 lines
2.9 KiB
Markdown
77 lines
2.9 KiB
Markdown
---
|
|
type: architecture
|
|
title: Anniversary Matching
|
|
description: Rules and file boundaries used to discover Jekyll posts whose publication anniversary is exactly ten years before the current date.
|
|
tags: [matching, jekyll, anniversary, posts]
|
|
timestamp: 2026-08-04T18:35:00Z
|
|
---
|
|
|
|
# Purpose
|
|
|
|
`tenbackward.matching` scans the synchronized blog at
|
|
`<blog_dir>/_posts/blog` and returns posts whose date is exactly ten years
|
|
before the current date. The current date is evaluated in the configured
|
|
IANA timezone, defaulting to `Europe/Berlin` in the matcher.
|
|
|
|
# Discovery Rules
|
|
|
|
1. Walk every Markdown file below the configured post root recursively.
|
|
2. Parse YAML front matter when present.
|
|
3. Require a filename stem shaped as `YYYY-MM-DD-slug` with a valid calendar
|
|
date and non-empty slug.
|
|
4. Prefer a valid front matter `date`; otherwise use the date in the filename.
|
|
5. Match the post year to `today.year - 10` and the month/day to today.
|
|
6. Skip posts with `published: false`.
|
|
7. Return a `MatchedPost` containing the relative path, title, date, and
|
|
canonical site URL. If front matter has no title, use the filename slug.
|
|
|
|
# Leap-Day Behavior
|
|
|
|
A February 29 post matches February 29 when the current year is a leap year.
|
|
In a non-leap year it matches March 1, preserving one anniversary event for
|
|
leap-day posts.
|
|
|
|
# Output and Integration
|
|
|
|
`find_anniversary_matches()` returns `MatchedPost` values for callers that
|
|
need metadata. `iter_anniversary_paths()` yields only relative paths; the
|
|
pipeline uses those paths as deduplication identifiers in the
|
|
[system state store](/architecture/system-overview.md) and persists new IDs in
|
|
`posted.json`.
|
|
|
|
Unreadable files, malformed front matter, invalid filenames, unpublished
|
|
posts, and unexpected per-file errors are skipped with structured warning
|
|
events rather than aborting the full scan.
|
|
|
|
# Key Files
|
|
|
|
| Path | Responsibility |
|
|
|---|---|
|
|
| `/repo/src/tenbackward/matching.py` | Date parsing, Jekyll front matter handling, anniversary rules, URL construction, and recursive scanning. |
|
|
| `/repo/src/tenbackward/main.py` | Supplies the blog post root and site URL, then applies state deduplication. |
|
|
| `/repo/tests/test_matching.py` | Covers filename/front matter parsing, date matching, unpublished posts, malformed files, URL output, and leap-day behavior. |
|
|
| `/repo/src/tenbackward/blog.py` | Ensures the source repository is cloned or fast-forwarded before matching. |
|
|
|
|
# Examples
|
|
|
|
## Matching post
|
|
|
|
On 2026-08-04, a file named
|
|
`_posts/blog/2016/2016-08-04-release.md` is eligible. Its identifier is
|
|
`2016/2016-08-04-release.md` and its generated URL is:
|
|
|
|
```text
|
|
https://example.com/2016/08/04/release/
|
|
```
|
|
|
|
## Skipped post
|
|
|
|
A file with `published: false`, an invalid date, or a non-matching
|
|
month/day is not yielded and does not enter `posted.json`.
|
|
|
|
# Related
|
|
|
|
* [Pipeline Runner](/architecture/pipeline-runner.md)
|
|
* [System Architecture](/architecture/system-overview.md)
|
|
* [Daily Run Guide](/guides/daily-run.md)
|