Skip to content
This repository was archived by the owner on Sep 23, 2026. It is now read-only.
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Session log — 2026-08-31

- **Session:** https://claude.ai/code/session_01UyJ1bMbnS5q9SM2ZQhDzAZ
- **Model:** Claude Sonnet 5 (`claude-sonnet-5`)
- **Repos touched:** `localthought/reflector` (this repo)
- **Redactions applied:** none needed — no secrets or personal information appeared in this session.

This log records the substantive human prompts and the assistant's
substantive outputs, per the scoping explained in
[`docs/ai-logs/README.md`](../README.md). It omits the coding assistant's
internal system prompt, tool-call plumbing, and other harness scaffolding.

---

## Turn 1

**User prompt:** https://github.com/michielbdejong/devlog/issues/64

**Assistant output (summarized):**

Read devlog issue #64 ("TUBS 1b+3 milestone report"), a personal devlog note
asserting that NLnet MOU milestones 1b and 3 were delivered (bidirectional
functionality per `localthought/syncables#11`, the Reflector repo for
milestone 3, plus the OpenAPI extensions and overlays repos), everything
open source and demonstrable live. Since the issue itself was not a
concrete code request and this session's designated work branch was in the
`reflector` repo rather than `devlog`, asked the user what the actual
deliverable in this repo should be; they chose a milestone-evidence
document to substantiate the claims with concrete evidence from this repo,
as a source document for the eventual NLnet report.

Surveyed the repo for existing milestone/NLnet-reporting conventions (none
found), then gathered evidence for milestone 3 (Reflector's cross-system
reflection engine): the README's "Reflecting between two systems" section
and its live-validation status callout, the commit/PR history implementing
it (#23–#29, the GitHub-shape `syncables` bump, the two-endpoint config),
and the harness (`harness/`) that independently exercises the
`reflected`/`mismatch`/`timeout`/`looped`/cross-shape scenarios. Re-ran
`pnpm test` (88/88 passing) and `pnpm test:harness` (9/9 passing) to attach
current, verified numbers rather than reusing stale claims. For milestone
1b (bidirectional functionality in `syncables`), noted that repo was
outside this session's access and did not fabricate independent
verification of its README claim — recorded only what this repo can
confirm (the pinned `syncables@0.17.1` dependency and the reflection
behavior built on top of it).

Wrote [`docs/milestones/1b-3-report.md`](../../docs/milestones/1b-3-report.md)
with this evidence, explicit citations (commit hashes, issue numbers, file
paths), a live-demo walkthrough, and an explicit "known scope limits"
section (the Devonian cross-shape mapping step is out of scope for the base
engine; token-auth reflection mode and interactive OAuth mode are mutually
exclusive per instance) so the report doesn't overstate what was built.
127 changes: 127 additions & 0 deletions docs/milestones/1b-3-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Milestone 1b + 3 evidence report

Source: [michielbdejong/devlog#64](https://github.com/michielbdejong/devlog/issues/64)
("TUBS 1b+3 milestone report"). That issue is a devlog note asserting the
NLnet MOU deliverables for milestone 1b and milestone 3 are done. This
document collects the concrete evidence for the claims that fall inside
this repository (milestone 3, plus what this repo can independently confirm
about the milestone 1b dependency), gathered on 2026-08-31 against
`main` (commit `a807916`).

## Milestone 3 — Reflector: reflecting between two systems of record

Milestone 3's deliverable, per the [README](../../README.md#reflecting-between-two-systems-eg-two-github-issue-trackers),
is that Reflector can **actively reflect records between two endpoints**
(A and B), not just sync one system into a local copy — demonstrated on two
independent GitHub issue trackers: issues created on one are copied to the
other, open/closed state is kept in agreement, and comments are copied
across.

### What was built

| Piece | Commit(s) |
| --- | --- |
| Vendored GitHub Issues OpenAPI document + overlays | `bd5e487` (#23) |
| Static API-key/PAT auth mode (no OAuth needed for token-auth endpoints) | `1714eee` (#24) |
| Cross-system reflection engine for issues | `73166bc` (#25) |
| Hidden HTML-comment origin marker (loop prevention) | `01ceb86` (#26) |
| Reflect issue open/closed state across the mirrored pair | `1613ea4` (#27) |
| Reflect issue comments across the mirrored pair | `e8ad3f5` (#28) |
| Background reflect loop, on-demand `POST /api/reflect`, persisted id-map | `481d0c8` (#29) |
| Two-endpoint (A/B) config + docs | `db60814` |
| Bump to `syncables@0.17.1` for GitHub-shape support | `8c86912`, `8623d39` |

Runtime surface: `POST /api/reflect` triggers a pass on demand and returns a
summary of what it created and the state changes it propagated;
`GET /api/reflect/status` inspects the background loop, which otherwise runs
every `REFLECT_INTERVAL_MS` (default 60s). See the README's
[Reflecting between two systems](../../README.md#reflecting-between-two-systems-eg-two-github-issue-trackers)
section for full configuration (`REFLECT_A_REPO`/`REFLECT_B_REPO`,
`REFLECT_A_TOKEN`/`REFLECT_B_TOKEN`, `REFLECT_DIRECTION`).

### Live validation

Per the README's status callout, the reflection engine has been **validated
live against two real GitHub repositories** — create, idempotent re-runs,
open/closed state both ways, and comments — in addition to the automated
test suite against a faithful in-memory GitHub stand-in. It depends on
GitHub-shape support added to the sync engine itself
([localthought/syncables#4](https://github.com/localthought/syncables/issues/4)–[#6](https://github.com/localthought/syncables/issues/6),
released as `syncables` 0.17.1 on npm).

### Automated test evidence (re-run for this report)

```
$ pnpm test # __tests__/unit/**, vitest
Test Files 19 passed (19)
Tests 88 passed (88)

$ pnpm test:harness # harness/**, vitest
Test Files 3 passed (3)
Tests 9 passed (9)
```

The harness (`harness/`, see [`harness/README.md`](../../harness/README.md))
is a separate, SUT-independent test rig: a **Driver** writes changes to a
fake platform, a **StubReflector** stands in for Reflector, a **Reviewer**
observes the target through fresh clients, and an oracle judges correctness
without trusting the reflector's own mapping. It exercises the failure
modes a grading reviewer would ask about, not just the happy path:
`reflected` (correct), `mismatch` (wrong content, e.g. a dropped field),
`timeout` (record never arrives), `looped` (ping-pong via origin-marker
echo suppression), and cross-shape mapping (a differently-shaped target
platform, judged by a mapping-aware oracle) — added across
`ab2dcd2`, `ec25bc4`, `8c86912`.

### Known scope limits (for accurate reporting)

- Reconciling two endpoints with genuinely different record shapes beyond
GitHub Issues is a later "Devonian" mapping step, called out as
out-of-scope for the base engine in the README; the two-endpoint config
already keeps the documents separate so that work has somewhere to plug
in.
- Token-auth reflection mode (A/B) and the interactive per-user OAuth mode
(single system, local-first copy) are mutually exclusive per instance —
when both `REFLECT_*_REPO` are set, the interactive "Connect" flow is
disabled.

## Milestone 1b — bidirectional functionality (syncables)

Reflector consumes `syncables` as a released npm dependency
(`syncables@0.17.1`, pinned in [`package.json`](../../package.json)).
The bidirectional GitHub-issue reflection above was built on top of
`syncables`' local-first create/update/delete with background retry and
rollback, it works end-to-end against it, in both the live validation and the
harness's `reflected`/`mismatch`/`timeout`/`looped` scenarios.
See [syncables readme](https://github.com/localthought/syncables#nlnet-milestone-1)
for a more detailed description of how the bi-directional version of Syncables works.

## Supporting repos referenced by the issue

- **[localthought/syncables](https://github.com/localthought/syncables)** —
the sync engine; milestone 1b's bidirectional functionality.
- **[localthought/overlays](https://github.com/localthought/overlays)** —
the OpenAPI Overlays (pagination + CRUD-causality) that this repo
vendors under [`spec/overlays/`](../../spec/overlays) and applies to the
vendored OpenAPI documents at startup (see
[`src/sync/document.ts`](../../src/sync/document.ts) and
[`src/sync/overlay.ts`](../../src/sync/overlay.ts)).
- **OpenAPI extensions repo** (pagination + CRUD-causality extension
definitions consumed by the overlays above) — referenced by the issue;
not independently checked from this session.

All of the above, plus this repo, are public and open source.

## How to see it live

1. Set the two-endpoint env vars from the README's
[GitHub setup](../../README.md#reflecting-between-two-systems-eg-two-github-issue-trackers)
example (`OPENAPI_PATH`/`OVERLAY_DIR` pointed at
`spec/github-issues.openapi.yaml` / `spec/overlays/github`,
`REFLECT_A_REPO`/`REFLECT_A_TOKEN`, `REFLECT_B_REPO`/`REFLECT_B_TOKEN`,
`REFLECT_DIRECTION=bidirectional`) against two real GitHub repos.
2. `pnpm build && pnpm start`.
3. Create an issue (or comment, or close one) on either repo and either wait
for the background loop (`REFLECT_INTERVAL_MS`, default 60s) or trigger a
pass on demand with `POST /api/reflect`; check `GET /api/reflect/status`
for the loop's state.
Loading