From 68b430af01608bff7ee8aaaa41915f506478fe58 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Thu, 28 May 2026 15:18:32 +0700 Subject: [PATCH] chore(plans): remove completed plans and historical reports All referenced work shipped; planning artifacts available in git history. --- .../phase-01-go-raw-socket-sender.md | 123 ------------- ...phase-02-compose-orchestration-and-docs.md | 111 ------------ .../plan.md | 53 ------ .../plan.md | 50 ------ ...phase-01-dockerfile-and-workflow-labels.md | 165 ------------------ .../plan.md | 42 ----- ...y-naming-rule-and-supersede-prior-plans.md | 77 -------- ...name-couchbase-image-to-service-version.md | 103 ----------- ...e-03-port-oci-labels-to-couchbase-image.md | 105 ----------- .../plan.md | 53 ------ ...528-1007-image-naming-convention-report.md | 108 ------------ ...-image-naming-convention-reframe-report.md | 128 -------------- ...-1312-image-naming-final-verdict-report.md | 98 ----------- ...0925-scribe-cleanup-verification-report.md | 141 --------------- ...21-scribe-oci-labels-and-cleanup-report.md | 95 ---------- ...-oci-labels-license-verification-report.md | 61 ------- ...-license-and-source-verification-report.md | 29 --- ...0925-scribe-cleanup-verification-report.md | 94 ---------- 18 files changed, 1636 deletions(-) delete mode 100644 plans/260527-1702-scribe-example-go-sender/phase-01-go-raw-socket-sender.md delete mode 100644 plans/260527-1702-scribe-example-go-sender/phase-02-compose-orchestration-and-docs.md delete mode 100644 plans/260527-1702-scribe-example-go-sender/plan.md delete mode 100644 plans/260528-1110-image-naming-convention-decision/plan.md delete mode 100644 plans/260528-1221-scribe-oci-labels-expansion/phase-01-dockerfile-and-workflow-labels.md delete mode 100644 plans/260528-1221-scribe-oci-labels-expansion/plan.md delete mode 100644 plans/260528-1324-rename-couchbase-to-convention-b/phase-01-codify-naming-rule-and-supersede-prior-plans.md delete mode 100644 plans/260528-1324-rename-couchbase-to-convention-b/phase-02-rename-couchbase-image-to-service-version.md delete mode 100644 plans/260528-1324-rename-couchbase-to-convention-b/phase-03-port-oci-labels-to-couchbase-image.md delete mode 100644 plans/260528-1324-rename-couchbase-to-convention-b/plan.md delete mode 100644 plans/reports/brainstorm-260528-1007-image-naming-convention-report.md delete mode 100644 plans/reports/brainstorm-260528-1015-image-naming-convention-reframe-report.md delete mode 100644 plans/reports/brainstorm-260528-1312-image-naming-final-verdict-report.md delete mode 100644 plans/reports/code-review-260528-0925-scribe-cleanup-verification-report.md delete mode 100644 plans/reports/code-review-260528-1221-scribe-oci-labels-and-cleanup-report.md delete mode 100644 plans/reports/researcher-260528-1221-scribe-oci-labels-license-verification-report.md delete mode 100644 plans/reports/researcher-260528-1324-couchbase-license-and-source-verification-report.md delete mode 100644 plans/reports/tester-260528-0925-scribe-cleanup-verification-report.md diff --git a/plans/260527-1702-scribe-example-go-sender/phase-01-go-raw-socket-sender.md b/plans/260527-1702-scribe-example-go-sender/phase-01-go-raw-socket-sender.md deleted file mode 100644 index e719470..0000000 --- a/plans/260527-1702-scribe-example-go-sender/phase-01-go-raw-socket-sender.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -phase: 1 -title: Go raw-socket sender -status: completed -priority: P2 -effort: 2h -dependencies: [] ---- - -# Phase 1: Go raw-socket sender - -## Overview - -A tiny Go program that connects to the Scribe daemon over TCP and sends `LogEntry` -messages by hand-encoding the Thrift framed binary `Log()` RPC — stdlib only, no Apache -Thrift dependency, no generated bindings. Compiles to a small static binary in a -multi-stage Docker build. - -## Requirements - -- Functional: connect to `SCRIBE_HOST:SCRIBE_PORT`, send `SCRIBE_COUNT` messages under - category `SCRIBE_CATEGORY`, parse the `ResultCode` reply, log OK/TRY_LATER, exit 0 on success. -- Functional: retry the initial connect (~10s, ~1s interval) so a cold `docker compose up` - does not fail before Scribe is listening. -- Non-functional: no external Go modules (stdlib `net`, `encoding/binary`, `os`, `time`, `log`). -- Non-functional: static binary (`CGO_ENABLED=0`); minimal runtime image. - -## Architecture - -### Scribe Thrift contract (from facebookarchive/scribe IDL) - -```thrift -enum ResultCode { OK = 0, TRY_LATER = 1 } -struct LogEntry { 1: string category; 2: string message; } -service scribe { ResultCode Log(1: list messages); } -``` - -### Wire format to produce - -- **Transport:** `TFramedTransport` → 4-byte big-endian frame length prefixes the payload. -- **Protocol:** `TBinaryProtocol`, **non-strict** message header (matches README client which - uses `strictWrite=False`; Scribe C++ server reads with `strict_read=false`, accepts it). - -Thrift type IDs used: `STOP=0`, `I32=8`, `STRING=11`, `STRUCT=12`, `LIST=15`. All ints big-endian. - -**Request payload (`Log` CALL):** -1. Message begin (non-strict): `string "Log"` (i32 len + bytes) · `i8 msgType=1 (CALL)` · `i32 seqid=0` -2. Args struct `Log_args`: - - field begin: `i8 type=15 (LIST)` · `i16 id=1` - - list begin: `i8 elemType=12 (STRUCT)` · `i32 size=N` - - per `LogEntry`: - - field: `i8 11 (STRING)` · `i16 1` · writeString(category) - - field: `i8 11 (STRING)` · `i16 2` · writeString(message) - - `i8 0 (STOP)` - - args struct: `i8 0 (STOP)` -3. Prepend `i32` total length → frame. - -`writeString(s)` = `i32 len(s)` + UTF-8 bytes. - -**Response parse (minimal):** -1. Read 4-byte frame length, then that many bytes. -2. Message begin (non-strict): i32 name-len + name + `i8 msgType` + `i32 seqid`. -3. Field begin `i8 type` · `i16 id`; for return value id=0 type=I32 → read `i32` ResultCode. -4. Map 0→OK, 1→TRY_LATER; anything else → log raw + treat non-zero as failure. - -### Connect-retry - -Loop `net.DialTimeout("tcp", addr, 2s)` up to 10 attempts, 1s between failures; fatal after. - -## Related Code Files - -- Create: `scribe/example/sender/main.go` — sender program (encode/send/parse + retry). -- Create: `scribe/example/sender/go.mod` — `module scribe-example-sender` / `go 1.22`, stdlib only. -- Create: `scribe/example/sender/Dockerfile` — multi-stage build. - -### Dockerfile (multi-stage) - -```dockerfile -FROM golang:1.22-alpine AS build -WORKDIR /src -COPY go.mod . -COPY main.go . -RUN CGO_ENABLED=0 go build -o /sender . - -FROM alpine:3.20 -COPY --from=build /sender /sender -ENTRYPOINT ["/sender"] -``` - -### main.go env inputs (with defaults) - -| Env | Default | Purpose | -|-----|---------|---------| -| `SCRIBE_HOST` | `scribe` | daemon hostname (compose service name) | -| `SCRIBE_PORT` | `1463` | Thrift port | -| `SCRIBE_CATEGORY` | `example` | message category → log subdir | -| `SCRIBE_COUNT` | `5` | number of LogEntry messages to send | - -## Implementation Steps - -1. Create `scribe/example/sender/go.mod` (module name + `go 1.22`). -2. Write `main.go`: - - read env with defaults; build `bytes.Buffer` helpers for `i8/i16/i32/string`. - - `buildLogFrame(entries)` → payload then 4-byte length prefix. - - connect-retry loop → write frame → read+parse response frame → log ResultCode. - - `os.Exit(0)` on OK; non-zero exit on connect failure or non-OK. -3. Write the multi-stage `Dockerfile`. -4. Local sanity build: `docker build -t scribe-sender scribe/example/sender` (verify compiles). - -## Success Criteria - -- [ ] `docker build scribe/example/sender` succeeds (binary compiles, no module fetch). -- [ ] Run against a live scribe container: sender logs `sent N messages, result=OK` and exits 0. -- [ ] Sender survives a cold start (scribe not yet listening) via the retry loop. - -## Risk Assessment - -- **Hand-encoded Thrift correctness** — wire format above is the stable 0.9.1 binary layout; - keep helpers tiny and comment each field. Mitigation: validate end-to-end in Phase 2 by - confirming the written log file contains the exact messages. -- **Strict vs non-strict header** — if the server unexpectedly rejects non-strict, switch - message-begin to strict (`i32 version=0x80010001`, name, `i32 seqid`). Documented here as - the fallback; default is non-strict to match the README client. diff --git a/plans/260527-1702-scribe-example-go-sender/phase-02-compose-orchestration-and-docs.md b/plans/260527-1702-scribe-example-go-sender/phase-02-compose-orchestration-and-docs.md deleted file mode 100644 index c2af6cd..0000000 --- a/plans/260527-1702-scribe-example-go-sender/phase-02-compose-orchestration-and-docs.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -phase: 2 -title: Compose orchestration and docs -status: completed -priority: P2 -effort: 1h -dependencies: - - 1 ---- - -# Phase 2: Compose orchestration and docs - -## Overview - -Wire the Scribe daemon and the Go sender (Phase 1) into a single `docker compose up` -demo, bind-mount logs to a host-visible folder, and document run + verify steps. End -result: one command produces real log files under `scribe/example/logs/`. - -## Requirements - -- Functional: `docker compose up` (from `scribe/example/`) starts Scribe with the repo's - `config/scribe.conf`, runs the sender once, and writes files to host `./logs`. -- Functional: logs are inspectable on the host without entering the container. -- Non-functional: scribe service uses published `ghcr.io/tiennm99/scribe:2.2` (no local build). -- Non-functional: example README is self-contained (run, verify, troubleshoot). - -## Architecture - -### docker-compose.yml - -```yaml -services: - scribe: - image: ghcr.io/tiennm99/scribe:2.2 - ports: - - "1463:1463" - volumes: - - ../config/scribe.conf:/etc/scribe/scribe.conf:ro - - ./logs:/var/log/scribe - restart: unless-stopped - - sender: - build: ./sender - depends_on: - - scribe - environment: - - SCRIBE_HOST=scribe - - SCRIBE_PORT=1463 - - SCRIBE_CATEGORY=example - - SCRIBE_COUNT=5 -``` - -Notes: -- Sender reaches Scribe over the compose network by service name `scribe:1463` (internal), - independent of the host `1463:1463` mapping. -- `depends_on` only orders start, not readiness — the Phase 1 retry loop covers the gap. -- Sender is one-shot: it sends then exits; scribe keeps running (`restart: unless-stopped`). - -### Expected on-disk result - -``` -scribe/example/logs/ -└── example/ - └── example-_00000 # contains the 5 sent messages -``` - -(Category `example` → subdir under the default catch-all store's `file_path=/var/log/scribe`.) - -## Related Code Files - -- Create: `scribe/example/docker-compose.yml` -- Create: `scribe/example/logs/.gitkeep` — keep the bind-mount dir in git, empty. -- Create: `scribe/example/README.md` — run/verify/troubleshoot for the example. -- Modify: `scribe/README.md` — add a short "Runnable example" pointer linking to `example/`. - -### scribe/example/README.md outline - -1. **What it does** — one command boots Scribe + sends test messages → log files appear. -2. **Run** — `cd scribe/example && docker compose up --build`. -3. **Verify** — show `scribe/example/logs/example/example-*_00000` and `cat` a line. -4. **Customize** — env vars (`SCRIBE_CATEGORY`, `SCRIBE_COUNT`), pointer to `config/scribe.conf`. -5. **Troubleshoot** — empty logs dir = no messages sent yet; Linux bind-mount permissions caveat. -6. **Stop** — `docker compose down`. - -## Implementation Steps - -1. Create `scribe/example/docker-compose.yml` per spec above. -2. Create `scribe/example/logs/.gitkeep`. -3. Write `scribe/example/README.md` per outline. -4. Add a "Runnable example" subsection to `scribe/README.md` linking to `example/`. -5. End-to-end test: `cd scribe/example && docker compose up --build`; confirm a log file - appears under `logs/example/` containing the sent messages; `docker compose down`. - -## Success Criteria - -- [ ] `docker compose up --build` starts both services without manual steps. -- [ ] After the sender exits, `scribe/example/logs/example/example-*_00000` exists on host. -- [ ] That file contains the test messages sent by the Go sender. -- [ ] `scribe/example/README.md` documents run, verify, and the Linux permission caveat. -- [ ] `scribe/README.md` links to the example. - -## Risk Assessment - -- **Bind-mount permissions (native Linux)** — Scribe runs as non-root user `scribe` - (`scribe/Dockerfile:107-110`); host `./logs` may reject its writes. On Docker Desktop - (Windows/macOS) this is normally fine. Mitigation: document `chmod 777 ./logs` (or matching - uid) in the README troubleshoot section. -- **Stale relative paths** — `../config/scribe.conf` and `./sender` build context are relative - to `scribe/example/`; compose must be run from that dir. Documented in README run step. -- **Empty logs confusion** — if the sender fails silently, logs dir stays empty. Mitigation: - sender logs success/failure to stdout (`docker compose` output) and exits non-zero on failure. diff --git a/plans/260527-1702-scribe-example-go-sender/plan.md b/plans/260527-1702-scribe-example-go-sender/plan.md deleted file mode 100644 index 5270651..0000000 --- a/plans/260527-1702-scribe-example-go-sender/plan.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Scribe runnable example with Go test sender -description: >- - Self-contained scribe/example/ that boots the Scribe daemon and a Go sender so - docker compose up writes visible log files to host ./logs -status: completed -priority: P2 -branch: main -tags: - - scribe - - example - - docker-compose - - golang - - thrift -blockedBy: [] -blocks: [] -created: '2026-05-27T10:27:22.391Z' -createdBy: 'ck:plan' -source: skill ---- - -# Scribe runnable example with Go test sender - -## Overview - -Add `scribe/example/` — a one-command demo proving the Scribe config actually writes logs. -`docker compose up` starts the Scribe daemon (published image, mounting the repo's -`config/scribe.conf`) plus a tiny Go sender that connects over Thrift, pushes a few -`LogEntry` messages, and exits. Resulting log files land in host-visible `./logs`. - -Scribe is receive-only: it writes nothing until a client sends Thrift messages. The Go -sender is what makes the example "write logs". The sender hand-encodes the Thrift framed -binary `Log()` call using only the Go stdlib (no codegen, no external modules) — chosen for -the smallest, most deterministic build (approach G1 from brainstorm). - -## Phases - -| Phase | Name | Status | -|-------|------|--------| -| 1 | [Go raw-socket sender](./phase-01-go-raw-socket-sender.md) | Completed | -| 2 | [Compose orchestration and docs](./phase-02-compose-orchestration-and-docs.md) | Completed | - -## Key Decisions (from brainstorm) - -- Sender language: **Go**, raw-socket stdlib only (no Apache Thrift lib, no generated bindings). -- Logs: **host bind mount** `scribe/example/logs` → container `/var/log/scribe`. -- Scribe service uses the **published image** `ghcr.io/tiennm99/scribe:2.2` (no local build needed). -- README's existing Python client snippet stays as-is (documented "real API" reference). - -## Dependencies - -None. New folder only; touches no existing image build. Reuses `scribe/config/scribe.conf` -(read-only mount) and the published `scribe:2.2` image. diff --git a/plans/260528-1110-image-naming-convention-decision/plan.md b/plans/260528-1110-image-naming-convention-decision/plan.md deleted file mode 100644 index 57bdd8c..0000000 --- a/plans/260528-1110-image-naming-convention-decision/plan.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -status: superseded -supersededBy: 260528-1324-rename-couchbase-to-convention-b ---- - -# Image Naming Convention - Decision Parked - -> **Superseded by [260528-1324-rename-couchbase-to-convention-b](../260528-1324-rename-couchbase-to-convention-b/plan.md) on 2026-05-28.** User chose Convention B; see superseding plan for rationale. - -Status: **SUPERSEDED** - Convention B locked in via 260528-1324 -Created: 2026-05-28 11:10 -Owner: tiennm99 - -## Question - -How should this repo name its Docker images? - -- Convention A (current for 3/4): `-:` e.g. `couchbase-2.5:2.5.2` -- Convention B (current for scribe): `:` e.g. `scribe:2.2` (Docker-Hub-official style) - -## Context - -- 4 images total at brainstorm time: `couchbase-2.5`, `gradle-8`, `oraclejdk-8`, `scribe` -- `gradle-8` and `oraclejdk-8` dropped 2026-05-28 (this commit) - decision now only spans `couchbase-2.5` + scribe -- scribe diverges from the rest -- Subdir already named `scribe-2.2/` regardless of which convention wins - -## Recommendation (from brainstorm) - -**Convention A**, rename scribe to `scribe-2.2`. Decisive arguments: - -1. `latest` semantics break under B for archived software (newest-wins misleads users searching for legacy versions) -2. Attestation lineage cleaner per-line under A -3. Docker-official `python:3.x` analogy doesn't transfer - those are sliding-window builds; this repo is a museum of frozen artifacts -4. Migration A = ~5 edits; B = ~15 edits + orphan-package cleanup + new `latest` policy - -See reports: -- `plans/reports/brainstorm-260528-1007-image-naming-convention-report.md` (initial) -- `plans/reports/brainstorm-260528-1015-image-naming-convention-reframe-report.md` (re-frame, stronger reasoning, same conclusion) - -## Decisions pending - -1. **Approve Convention A?** If yes: rename scribe to `scribe-2.2` (~5 edits). -2. **Codify rule** in README + CLAUDE.md as part of same change, or separate task? -3. **Orphan packages** post-rename: delete `ghcr.io/tiennm99/scribe` + Docker Hub counterpart, or tombstone in README? - -## When to revisit - -- Before adding a new image (so the new image follows the chosen convention) -- Or sooner if user wants to lock the rule down diff --git a/plans/260528-1221-scribe-oci-labels-expansion/phase-01-dockerfile-and-workflow-labels.md b/plans/260528-1221-scribe-oci-labels-expansion/phase-01-dockerfile-and-workflow-labels.md deleted file mode 100644 index 6993969..0000000 --- a/plans/260528-1221-scribe-oci-labels-expansion/phase-01-dockerfile-and-workflow-labels.md +++ /dev/null @@ -1,165 +0,0 @@ -# Phase 01 — Dockerfile + Workflow Labels - -**Status:** pending -**Effort:** ~20m - -## Context Links - -- Research report: `plans/reports/researcher-260528-1221-scribe-oci-labels-license-verification-report.md` -- metadata-action docs: https://github.com/docker/metadata-action (auto-injects 8 OCI labels by default; `labels:` input overrides them) - -## Key findings driving the design - -1. `docker/metadata-action@9ec57ed` (workflow line 40) auto-injects: `title`, `description`, `url`, `source`, `version`, `created`, `revision`, `licenses` — values derived from THIS repo's GitHub metadata. -2. CLI `--label` (which `docker/build-push-action` uses via `labels: ${{ steps.meta.outputs.labels }}`) OVERRIDES Dockerfile `LABEL` instructions at build time. So workflow builds today shadow the Dockerfile's labels for `version`, `description`, `source`. -3. Auto-injected `source` and `title` are WRONG for this image (point to our build repo / `docker-images` name, not Scribe upstream). Must be overridden in the workflow's `metadata-action.labels:` block. -4. Auto-injected `created` is correct (build timestamp). Keep it. -5. Manual `docker build` (no CI) skips metadata-action entirely, so Dockerfile labels still matter for that path. - -## Final label set on published image - -| Key | Value | Source | -|-----|-------|--------| -| `org.opencontainers.image.title` | `Facebook Legacy Scribe` | Dockerfile + workflow override | -| `org.opencontainers.image.description` | `Facebook Legacy Scribe - real-time log aggregation daemon` | Dockerfile + workflow override | -| `org.opencontainers.image.version` | `2.2` | Dockerfile + workflow override | -| `org.opencontainers.image.source` | `https://github.com/facebookarchive/scribe` | Dockerfile + workflow override | -| `org.opencontainers.image.licenses` | `Apache-2.0` | Dockerfile + workflow override | -| `org.opencontainers.image.created` | (build timestamp) | metadata-action auto | -| `org.opencontainers.image.url` | (our repo URL) | metadata-action auto (acceptable — IS where image is built) | -| `org.opencontainers.image.revision` | (git SHA of our repo) | metadata-action auto (acceptable — identifies build recipe commit) | -| `maintainer` | `Tien Nguyen Minh ` | Dockerfile only (not OCI; metadata-action does not auto-inject) | - -## Files to modify - -### 1. `scribe-2.2/Dockerfile` — replace lines 70-73 - -**Before:** -```dockerfile -LABEL maintainer="Tien Nguyen Minh " -LABEL org.opencontainers.image.version="2.2" -LABEL org.opencontainers.image.description="Facebook Legacy Scribe - real-time log aggregation daemon" -LABEL org.opencontainers.image.source="https://github.com/facebookarchive/scribe" -``` - -**After:** -```dockerfile -LABEL maintainer="Tien Nguyen Minh " -LABEL org.opencontainers.image.title="Facebook Legacy Scribe" -LABEL org.opencontainers.image.description="Facebook Legacy Scribe - real-time log aggregation daemon" -LABEL org.opencontainers.image.version="2.2" -LABEL org.opencontainers.image.source="https://github.com/facebookarchive/scribe" -LABEL org.opencontainers.image.licenses="Apache-2.0" -``` - -Order: `maintainer` first, then OCI labels grouped (title, description, version, source, licenses). Plain ASCII only. - -### 2. `.github/workflows/publish-scribe-2.2.yml` — extend metadata-action step (lines 38-47) - -**Before (lines 38-47):** -```yaml - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 - with: - images: | - ghcr.io/${{ github.actor }}/scribe - ${{ secrets.DOCKER_USERNAME }}/scribe - tags: | - type=raw,value=latest - type=raw,value=2.2 -``` - -**After:** -```yaml - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 - with: - images: | - ghcr.io/${{ github.actor }}/scribe - ${{ secrets.DOCKER_USERNAME }}/scribe - tags: | - type=raw,value=latest - type=raw,value=2.2 - labels: | - org.opencontainers.image.title=Facebook Legacy Scribe - org.opencontainers.image.description=Facebook Legacy Scribe - real-time log aggregation daemon - org.opencontainers.image.version=2.2 - org.opencontainers.image.source=https://github.com/facebookarchive/scribe - org.opencontainers.image.licenses=Apache-2.0 -``` - -Note: do NOT quote values in the metadata-action `labels:` block — quotes become part of the label value. metadata-action splits on `=` only. - -## Implementation steps - -1. Edit `scribe-2.2/Dockerfile` lines 70-73 per spec above. -2. Edit `.github/workflows/publish-scribe-2.2.yml` adding the `labels:` block after `tags:`. -3. Lint/validate yaml manually (no schema check needed — small change). -4. Stage only these 2 files. Leave the pending ASCII cleanup unstaged. -5. Commit: `feat(scribe): expand OCI image-spec labels` (conventional commit, no plan refs in message per global rules). -6. Push. Workflow triggers because path filter `scribe-2.2/**` and `.github/workflows/publish-scribe-2.2.yml` both match. -7. Validate (see below). - -## Commit plan - -**One commit for this plan.** Bundles Dockerfile + workflow because they describe the same change (label set expansion) and must land together to avoid a window where workflow builds and Dockerfile disagree. - -The existing pending ASCII cleanup is a separate logical commit — handle BEFORE or AFTER this plan, never in the same commit. Plan does not stage or modify those files. - -Commit message: -``` -feat(scribe): expand OCI image-spec labels - -Add image.title and image.licenses; override metadata-action defaults -in publish workflow so published image carries Scribe upstream source -and correct title rather than this repo's auto-derived values. -``` - -## Validation - -After workflow run completes and image is published: - -```bash -docker buildx imagetools inspect ghcr.io/tiennm99/scribe:2.2 --format '{{json .Manifest}}' -# OR inspect labels specifically: -docker pull ghcr.io/tiennm99/scribe:2.2 -docker inspect ghcr.io/tiennm99/scribe:2.2 --format '{{json .Config.Labels}}' | jq -``` - -Expected: all 5 OCI keys above present with the specified values; `created` set to a recent ISO-8601 timestamp; `url`/`revision` present (metadata-action defaults); `maintainer` present. - -For manual-build validation (no CI): -```bash -docker build -t scribe:2.2-local scribe-2.2 -docker inspect scribe:2.2-local --format '{{json .Config.Labels}}' | jq -``` -Expected: 5 OCI keys + `maintainer` from Dockerfile; no `created`/`url`/`revision` (those only exist via metadata-action). - -## Todo - -- [ ] Edit `scribe-2.2/Dockerfile` lines 70-73 — final 6-label block -- [ ] Edit `.github/workflows/publish-scribe-2.2.yml` — add `labels:` block to metadata-action step -- [ ] `git add scribe-2.2/Dockerfile .github/workflows/publish-scribe-2.2.yml` (explicit paths; do NOT stage other modified files) -- [ ] Verify `git status` shows only those two files staged; ASCII-cleanup files still unstaged -- [ ] Commit with conventional message above -- [ ] Push to `main` -- [ ] Wait for `publish-scribe-2.2.yml` workflow to complete (GitHub Actions tab) -- [ ] Run `docker inspect` validation against `ghcr.io/tiennm99/scribe:2.2` -- [ ] Confirm all 5 OCI labels carry expected values; tick this phase complete - -## Success criteria - -- Published image at `ghcr.io/tiennm99/scribe:2.2` AND `${DOCKER_USERNAME}/scribe:2.2` carries: - - `org.opencontainers.image.title=Facebook Legacy Scribe` - - `org.opencontainers.image.source=https://github.com/facebookarchive/scribe` (NOT this repo's URL) - - `org.opencontainers.image.licenses=Apache-2.0` - - `org.opencontainers.image.version=2.2` - - `org.opencontainers.image.description` with `Facebook Legacy Scribe - real-time log aggregation daemon` -- Workflow continues to publish `2.2` and `latest` tags (no regression). -- Manual `docker build scribe-2.2/` still works and produces labeled image. - -## Rollback - -Single commit revert: `git revert ` and force-trigger workflow. No data, no schema, no dependents — rollback is purely cosmetic metadata. diff --git a/plans/260528-1221-scribe-oci-labels-expansion/plan.md b/plans/260528-1221-scribe-oci-labels-expansion/plan.md deleted file mode 100644 index 6b0c125..0000000 --- a/plans/260528-1221-scribe-oci-labels-expansion/plan.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: "Expand OCI image-spec labels on scribe-2.2" -description: "Add title/licenses labels and override workflow defaults so published image has correct upstream metadata." -status: completed -priority: P3 -effort: 20m -branch: main -tags: [docker, oci, metadata, scribe] -created: 2026-05-28 ---- - -# Scribe-2.2 OCI Labels Expansion - -> **Completed 2026-05-28 via commits `afaa631` (ASCII cleanup) and `4ef74f3` (OCI labels). Pattern reused as template for Phase 03 of [260528-1324-rename-couchbase-to-convention-b](../260528-1324-rename-couchbase-to-convention-b/plan.md).** - -Single-pass metadata change. Adds `image.title` and `image.licenses` to the Dockerfile, and overrides the GitHub Actions `docker/metadata-action` defaults so the published image carries correct Scribe-upstream values rather than this repo's defaults. - -## Why this is not a one-line change - -`docker/metadata-action` auto-injects 8 OCI labels with values derived from THIS repo (`tiennm99/docker-images`). CLI `--label` overrides Dockerfile `LABEL` instructions for the same key, so the Dockerfile labels are effectively shadowed at workflow build time. Fix: override the relevant keys in the workflow's `metadata-action` `labels:` block. Keep Dockerfile labels as the manual-build fallback. - -## Decisions locked - -- Title: `Facebook Legacy Scribe` (consistent with existing description prefix). -- Licenses: `Apache-2.0` (verified, single license, no SPDX expression needed). -- `image.created`: let `metadata-action` auto-inject (build timestamp). No `--build-arg` plumbing. -- Skip: `url`, `documentation`, `vendor`, `revision`, `authors`. -- Override approach: BOTH Dockerfile (manual builds) AND workflow `labels:` block (CI builds). Same key/value in both places — single source of truth in plan, dual placement for two build paths. - -## Phases - -- [ ] Phase 01 — Dockerfile + workflow labels ([phase-01-dockerfile-and-workflow-labels.md](phase-01-dockerfile-and-workflow-labels.md)) - -## Files touched - -- `scribe-2.2/Dockerfile` (runtime stage, lines 70-73) -- `.github/workflows/publish-scribe-2.2.yml` (metadata-action step, lines 38-47) - -## Out of scope - -- Existing uncommitted ASCII cleanup across `scribe-2.2/**` — separate logical commit, untouched by this plan. -- Other images in the repo (only `scribe-2.2/` touched). diff --git a/plans/260528-1324-rename-couchbase-to-convention-b/phase-01-codify-naming-rule-and-supersede-prior-plans.md b/plans/260528-1324-rename-couchbase-to-convention-b/phase-01-codify-naming-rule-and-supersede-prior-plans.md deleted file mode 100644 index 94d5540..0000000 --- a/plans/260528-1324-rename-couchbase-to-convention-b/phase-01-codify-naming-rule-and-supersede-prior-plans.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -phase: 1 -title: "Codify naming rule and supersede prior plans" -status: completed -priority: P2 -effort: "15m" -commit: "2f7bfde" -dependencies: [] ---- - -# Phase 1: Codify naming rule and supersede prior plans - -## Overview - -Document Convention B in `README.md` and close out the two prior decision plans (parked `260528-1110-…` and completed `260528-1221-…`). One docs commit. - -## Requirements - -- Functional: rule is discoverable in README; prior plans no longer show as "pending" in `ck plan status`. -- Non-functional: plain ASCII; under ~25 lines added to README; no breaking link changes. - -## Architecture - -Single concern: decision record. Touches 3 markdown files. No code. - -## Related Code Files - -- Modify: `D:\tiennm99\docker-images\README.md` (append new "## Naming convention" section after the image-index table at L7-10) -- Modify: `D:\tiennm99\docker-images\plans\260528-1110-image-naming-convention-decision\plan.md` (frontmatter `status: superseded` + supersede pointer) -- Modify: `D:\tiennm99\docker-images\plans\260528-1221-scribe-oci-labels-expansion\plan.md` (frontmatter `status: completed` + commit refs) - -## Implementation Steps - -1. Append the codified rule to `README.md` immediately after the image-index table (before any per-image sections). Use this exact block (plain ASCII, no smart quotes, no em-dashes): - - ```markdown - ## Naming convention - - This repo uses Docker-Hub-style image names: `:`. - - - Subdirectory: `-/` (e.g. `couchbase-2.5/`, `scribe-2.2/`). Subdir holds the build context for one major version line. - - GHCR + Docker Hub image: `` (e.g. `couchbase`, `scribe`). No major-line suffix in the image name. - - Workflow file: `publish--.yml` (matches subdir for path-trigger clarity). - - Tags published per workflow: - - `` (e.g. `2.5.2`, `2.2`) - - `` (e.g. `2.5`) - optional alias - - `latest` - canonical build of the only major line this repo carries for the service. - - If a second major line of the same service is ever added to this repo, drop `latest` from both workflows and publish `-latest` tags instead. - ``` - -2. Update `plans/260528-1110-image-naming-convention-decision/plan.md`: - - Set frontmatter `status: superseded` (or add the field if missing). - - Add a top-of-body note: `> **Superseded by [260528-1324-rename-couchbase-to-convention-b](../260528-1324-rename-couchbase-to-convention-b/plan.md) on 2026-05-28.** User chose Convention B; see superseding plan for rationale.` - -3. Update `plans/260528-1221-scribe-oci-labels-expansion/plan.md`: - - Set frontmatter `status: completed`. - - Add a top-of-body note: `> **Completed 2026-05-28 via commits `afaa631` (ASCII cleanup) and `4ef74f3` (OCI labels). Pattern reused as template for Phase 03 of [260528-1324-rename-couchbase-to-convention-b](../260528-1324-rename-couchbase-to-convention-b/plan.md).**` - -4. Commit: `docs: codify Convention B naming rule and close prior decision plans` - -## Success Criteria - -- [ ] README contains "Naming convention" section with the 5 bullet structure above -- [ ] Parked 1110 plan marked superseded with link forward -- [ ] Completed 1221 plan marked completed with commit refs -- [ ] One commit, message starts with `docs:` -- [ ] `git diff --stat` for this phase touches exactly 3 files - -## Risk Assessment - -- **Risk:** future contributor adds a 2nd major-line service (e.g. `couchbase-6`) and forgets the `latest` rule, causing `couchbase:latest` to flip to the newer version mid-flight. **Mitigation:** the codified rule explicitly calls this out; future cross-plan scan would catch it. -- **Risk:** prior plans' `status: superseded` field may not be a recognized `ck plan` status. **Mitigation:** if `ck plan status` rejects, fall back to a body-level note plus removing the file from active scan via different means (e.g. archive flag). Verify after step 2. - -## Open question (not blocking) - -- Should the rule also live in a project-local `CLAUDE.md` so future Claude Code sessions auto-load it? Defaulted to README-only (KISS — repo has no CLAUDE.md today). Trivial to add later if it becomes painful. diff --git a/plans/260528-1324-rename-couchbase-to-convention-b/phase-02-rename-couchbase-image-to-service-version.md b/plans/260528-1324-rename-couchbase-to-convention-b/phase-02-rename-couchbase-image-to-service-version.md deleted file mode 100644 index bd42874..0000000 --- a/plans/260528-1324-rename-couchbase-to-convention-b/phase-02-rename-couchbase-image-to-service-version.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -phase: 2 -title: "Rename couchbase image to :" -status: completed -priority: P1 -effort: "10m" -commit: "3a0e31b" -dependencies: [1] ---- - -# Phase 2: Rename couchbase image to `:` - -## Overview - -Rename the published image from `couchbase-2.5` to `couchbase` across GHCR + Docker Hub. Keep subdirectory and workflow filename unchanged (path-trigger anchor). Add `2.5` major-line alias tag while we're here. - -## Requirements - -- Functional: after push + workflow run, `docker pull ghcr.io/tiennm99/couchbase:2.5.2` resolves; old `ghcr.io/tiennm99/couchbase-2.5:2.5.2` becomes orphan. -- Non-functional: subdirectory `couchbase-2.5/` not renamed; workflow filename not renamed. - -## Architecture - -Three files touch the literal string `couchbase-2.5` in an image-reference context: -- `.github/workflows/publish-couchbase-2.5.yml` - `images:` block (L42-43) + `subject-name:` (L61) -- `README.md` - image-index table row link target (`pkgs/container/couchbase-2.5` -> `pkgs/container/couchbase`) and the `docker pull ghcr.io/tiennm99/couchbase-2.5:2.5.2` example block in the Couchbase section. -- `couchbase-2.5/docker-compose.example.yml` - L3 `image: ghcr.io/tiennm99/couchbase-2.5:2.5.2` - -Subdir name and workflow filename are NOT image references; they stay. - -## Related Code Files - -- Modify: `D:\tiennm99\docker-images\.github\workflows\publish-couchbase-2.5.yml` -- Modify: `D:\tiennm99\docker-images\README.md` -- Modify: `D:\tiennm99\docker-images\couchbase-2.5\docker-compose.example.yml` - -## Implementation Steps - -1. Edit `.github/workflows/publish-couchbase-2.5.yml`: - - **Before (L42-47):** - ```yaml - images: | - ghcr.io/${{ github.actor }}/couchbase-2.5 - ${{ secrets.DOCKER_USERNAME }}/couchbase-2.5 - tags: | - type=raw,value=latest - type=raw,value=2.5.2 - ``` - - **After:** - ```yaml - images: | - ghcr.io/${{ github.actor }}/couchbase - ${{ secrets.DOCKER_USERNAME }}/couchbase - tags: | - type=raw,value=latest - type=raw,value=2.5 - type=raw,value=2.5.2 - ``` - - **Before (L61):** - ```yaml - subject-name: ghcr.io/${{ github.actor }}/couchbase-2.5 - ``` - - **After:** - ```yaml - subject-name: ghcr.io/${{ github.actor }}/couchbase - ``` - -2. Edit `README.md`: - - Image-index table row: link `[couchbase-2.5](https://github.com/tiennm99/docker-images/pkgs/container/couchbase-2.5)` -> `[couchbase](https://github.com/tiennm99/docker-images/pkgs/container/couchbase)`. Display text in the link also flips to `couchbase`. - - Couchbase section `docker pull ghcr.io/tiennm99/couchbase-2.5:2.5.2` example -> `docker pull ghcr.io/tiennm99/couchbase:2.5.2` - - "More options" GHCR URL in the same section also flips. - -3. Edit `couchbase-2.5/docker-compose.example.yml` L3: - - `image: ghcr.io/tiennm99/couchbase-2.5:2.5.2` -> `image: ghcr.io/tiennm99/couchbase:2.5.2` - -4. Commit: `refactor(couchbase): rename image package to couchbase (Convention B)` - -## Success Criteria - -- [ ] Workflow `images:` block lists `couchbase`, not `couchbase-2.5` -- [ ] Workflow `tags:` includes new `2.5` major-line alias -- [ ] Workflow `subject-name:` ends in `/couchbase` -- [ ] README image-index row link target is `pkgs/container/couchbase` -- [ ] `couchbase-2.5/docker-compose.example.yml` pulls from `ghcr.io/tiennm99/couchbase:2.5.2` -- [ ] `grep -r "tiennm99/couchbase-2.5" D:\tiennm99\docker-images\` (excluding plans/reports) returns 0 results -- [ ] One commit, message starts with `refactor(couchbase):` - -## Risk Assessment - -- **Risk:** stale `docker pull ghcr.io/tiennm99/couchbase-2.5:2.5.2` references in user environments break after orphan deletion. **Mitigation:** repo is one-maintainer; no known external consumers. Old package remains pullable until user deletes via UI (manual step, deferred). -- **Risk:** `2.5` tag alias confuses users into expecting it to track patches within 2.5.x. **Mitigation:** only one 2.5.x release exists (2.5.2); `2.5` is effectively a synonym. Codified rule in Phase 01 calls it an "optional alias". - -## Validation (after push, in Phase 03 or later) - -- Workflow run completes successfully on GitHub Actions -- `docker pull ghcr.io/tiennm99/couchbase:2.5.2` resolves -- `docker pull ghcr.io/tiennm99/couchbase:latest` resolves -- `docker pull ghcr.io/tiennm99/couchbase:2.5` resolves -- Root README image-index link resolves to a real GHCR page diff --git a/plans/260528-1324-rename-couchbase-to-convention-b/phase-03-port-oci-labels-to-couchbase-image.md b/plans/260528-1324-rename-couchbase-to-convention-b/phase-03-port-oci-labels-to-couchbase-image.md deleted file mode 100644 index 71d48c2..0000000 --- a/plans/260528-1324-rename-couchbase-to-convention-b/phase-03-port-oci-labels-to-couchbase-image.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -phase: 3 -title: "Port OCI labels to couchbase image" -status: completed -priority: P2 -effort: "10m" -commit: "afa2930" -dependencies: [2] ---- - -# Phase 3: Port OCI labels to couchbase image - -## Overview - -Add OCI image-spec labels to couchbase using the proven pattern from `scribe-2.2/Dockerfile` + `.github/workflows/publish-scribe-2.2.yml`. Both Dockerfile (manual-build path) and workflow `metadata-action.labels:` block (CI-build path) set the same values, since CLI `--label` from metadata-action overrides Dockerfile `LABEL` instructions. - -## Requirements - -- Functional: published image at `ghcr.io/tiennm99/couchbase:2.5.2` carries 5 OCI labels with correct values; metadata-action's auto-defaults (derived from THIS repo) do not shadow upstream-Couchbase metadata. -- Non-functional: plain ASCII; pattern matches scribe verbatim for consistency. - -## Architecture - -Mirror scribe-2.2's structure: -- `Dockerfile` runtime stage carries 5 `LABEL org.opencontainers.image.*` lines after `LABEL maintainer`. -- Workflow `metadata-action` step has a `labels:` block in YAML setting the same 5 keys (overrides metadata-action defaults). - -## Research input - -- `plans/reports/researcher-260528-1324-couchbase-license-and-source-verification-report.md` - - License: `Apache-2.0` (Couchbase Server 2.5.2, Dec 2012; BSL adoption was later, post-2021) - - `image.source`: `https://github.com/couchbase/docker` (general repo, not pinned commit) - -## Label values - -| Key | Value | -|-----|-------| -| `org.opencontainers.image.title` | `Couchbase Server 2.5` | -| `org.opencontainers.image.description` | `Legacy Couchbase Server (no official upstream image)` | -| `org.opencontainers.image.version` | `2.5.2` | -| `org.opencontainers.image.source` | `https://github.com/couchbase/docker` | -| `org.opencontainers.image.licenses` | `Apache-2.0` | - -`org.opencontainers.image.created`, `url`, `revision` left to metadata-action defaults (acceptable). - -## Related Code Files - -- Modify: `D:\tiennm99\docker-images\couchbase-2.5\Dockerfile` (insert 5 LABEL lines after L3 `LABEL maintainer`) -- Modify: `D:\tiennm99\docker-images\.github\workflows\publish-couchbase-2.5.yml` (add `labels:` block after `tags:` in metadata-action step) - -## Implementation Steps - -1. Edit `couchbase-2.5/Dockerfile`: - - **Before (L3):** - ```dockerfile - LABEL maintainer="Tien Nguyen Minh " - ``` - - **After:** - ```dockerfile - LABEL maintainer="Tien Nguyen Minh " - LABEL org.opencontainers.image.title="Couchbase Server 2.5" - LABEL org.opencontainers.image.description="Legacy Couchbase Server (no official upstream image)" - LABEL org.opencontainers.image.version="2.5.2" - LABEL org.opencontainers.image.source="https://github.com/couchbase/docker" - LABEL org.opencontainers.image.licenses="Apache-2.0" - ``` - -2. Edit `.github/workflows/publish-couchbase-2.5.yml` metadata-action step. Insert `labels:` block immediately after the `tags:` block (after Phase 02's edits): - - ```yaml - labels: | - org.opencontainers.image.title=Couchbase Server 2.5 - org.opencontainers.image.description=Legacy Couchbase Server (no official upstream image) - org.opencontainers.image.version=2.5.2 - org.opencontainers.image.source=https://github.com/couchbase/docker - org.opencontainers.image.licenses=Apache-2.0 - ``` - - Do NOT quote values in the `labels:` block - metadata-action splits on `=` only, quotes become part of the value. - -3. Commit: `feat(couchbase): expand OCI image-spec labels` - -## Success Criteria - -- [ ] Couchbase Dockerfile has 5 OCI LABEL lines after maintainer -- [ ] Workflow `metadata-action` step has `labels:` block with the same 5 keys, no quoted values -- [ ] One commit, message starts with `feat(couchbase):` -- [ ] After workflow runs: `docker inspect ghcr.io/tiennm99/couchbase:2.5.2 --format '{{json .Config.Labels}}'` returns all 5 OCI keys with upstream-Couchbase values (not auto-derived from this repo) - -## Risk Assessment - -- **Risk:** license verification relied on Wikipedia + Couchbase blog; if 2.5.2 binaries are actually licensed differently from Couchbase open-source code, the label is wrong. **Mitigation:** label is metadata, not legal claim; updateable. If Couchbase publishes a contradicting LICENSE.txt for 2.5.2, swap the label value in a one-line follow-up commit. -- **Risk:** workflow `labels:` block YAML indentation drift (it sits inside `metadata-action.with:`). **Mitigation:** match scribe's exact indentation in `publish-scribe-2.2.yml` L48-53 (proven working). - -## Validation (after push) - -- Workflow run on `main` after this phase's commit completes successfully. -- `docker pull ghcr.io/tiennm99/couchbase:2.5.2` then `docker inspect couchbase:2.5.2 --format '{{json .Config.Labels}}' | jq`. Expect: - - All 5 OCI keys above with specified values - - `org.opencontainers.image.created` set to recent ISO-8601 timestamp (metadata-action default) - - `org.opencontainers.image.url` and `org.opencontainers.image.revision` set to this repo's metadata (metadata-action default, acceptable) - - `maintainer` set to `Tien Nguyen Minh ` (Dockerfile only) -- Manual `docker build couchbase-2.5/ -t couchbase:test`; `docker inspect couchbase:test --format '{{json .Config.Labels}}'` shows 5 OCI keys + maintainer (no `created`/`url`/`revision` since metadata-action absent on manual build). diff --git a/plans/260528-1324-rename-couchbase-to-convention-b/plan.md b/plans/260528-1324-rename-couchbase-to-convention-b/plan.md deleted file mode 100644 index 7cda73d..0000000 --- a/plans/260528-1324-rename-couchbase-to-convention-b/plan.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "Apply Convention B naming: rename couchbase image and codify rule" -description: "Migrate this repo to Docker-Hub-style image naming (:). Rename ghcr.io/tiennm99/couchbase-2.5 -> couchbase. Port OCI labels to couchbase. Codify the rule in README. Close out prior naming-decision plans." -status: completed -priority: P2 -branch: "main" -tags: [docker, naming, convention, couchbase, oci] -blockedBy: [] -blocks: [260528-1110-image-naming-convention-decision] -created: "2026-05-28T06:30:23.203Z" -createdBy: "ck:plan" -source: skill ---- - -# Apply Convention B naming: rename couchbase image and codify rule - -## Overview - -Three brainstorm rounds had recommended Convention A (`-:`). User overruled on YAGNI grounds — A's load-bearing argument (`latest` semantics breaking on multi-major-line coexistence) is a future hypothetical, not a current need. Repo has only 2 images, both single-major-line. Convention B (`:`) is the Docker-Hub standard, shorter, cheaper to migrate. - -This plan implements Convention B: rename `ghcr.io/tiennm99/couchbase-2.5` to `couchbase` (and Docker Hub counterpart), keep `scribe` as-is (already conformant), port OCI labels to couchbase using the proven scribe pattern, codify the rule in `README.md`, and close out prior decision plans. - -## Phases - -| Phase | Name | Status | -|-------|------|--------| -| 1 | [Codify naming rule and supersede prior plans](./phase-01-codify-naming-rule-and-supersede-prior-plans.md) | Completed (`2f7bfde`) | -| 2 | [Rename couchbase image to :](./phase-02-rename-couchbase-image-to-service-version.md) | Completed (`3a0e31b`) | -| 3 | [Port OCI labels to couchbase image](./phase-03-port-oci-labels-to-couchbase-image.md) | Completed (`afa2930`) | - -## Dependencies - -- **Supersedes:** `plans/260528-1110-image-naming-convention-decision/` (parked "decide later" plan; this plan locks in Convention B and closes the loop). -- **Builds on:** `plans/260528-1221-scribe-oci-labels-expansion/` (completed via commits `afaa631` + `4ef74f3`). That plan's OCI label pattern is the template for Phase 03. - -## Research input - -- `plans/reports/researcher-260528-1324-couchbase-license-and-source-verification-report.md` — confirms Couchbase 2.5.2 license is `Apache-2.0`; recommends `image.source=https://github.com/couchbase/docker` (general repo, not pinned commit). - -## Commit strategy - -One commit per phase, three commits total. Pattern matches the just-shipped scribe work: `docs:`/`refactor:`/`feat:`. - -## Post-execution manual actions (not part of cook) - -1. Delete orphan packages via UI: `ghcr.io/tiennm99/couchbase-2.5` and `docker.io/${DOCKER_USERNAME}/couchbase-2.5`. -2. Validate: `docker pull ghcr.io/tiennm99/couchbase:2.5.2` and `docker inspect` shows OCI labels. - -## Out of scope - -- Subdirectory rename (`couchbase-2.5/` stays; subdir name is decoupled from image name under Convention B — codified in Phase 01's rule). -- Workflow filename rename (`publish-couchbase-2.5.yml` stays; path-trigger needs to match the subdir). -- New project-local `CLAUDE.md` — defaulted to README-only for KISS; flagged in Phase 01 as an optional add. diff --git a/plans/reports/brainstorm-260528-1007-image-naming-convention-report.md b/plans/reports/brainstorm-260528-1007-image-naming-convention-report.md deleted file mode 100644 index af6863b..0000000 --- a/plans/reports/brainstorm-260528-1007-image-naming-convention-report.md +++ /dev/null @@ -1,108 +0,0 @@ -# Image Naming Convention - Brainstorm - -## Current state (verified) - -| Subdir | GHCR image | Tags | Notes | -|---|---|---|---| -| couchbase-2.5/ | `couchbase-2.5` | `latest`, `2.5.2` | matches subdir | -| gradle-8/ | `gradle-8` | `latest`, `8.13` | matches subdir | -| oraclejdk-8/ | `oraclejdk-8` | `latest`, `8u201` | matches subdir | -| scribe-2.2/ | `scribe` | `latest`, `2.2` | **outlier** | - -Scribe diverges in `publish-scribe-2.2.yml` L43-44 (`images:`), L61 (`subject-name:`), and `README.md` L12 (package link). Subdir already correctly named `scribe-2.2/`. Workflow first added ~7 weeks ago - package fresh, blast radius low. - -## Convention - -`-` = **image name** (preserved product line). `` = **tag** (specific build). Differs from Docker Hub officials (`python`, `node`) because this repo specializes in archived/legacy software - each major line is its own write-once artifact with potentially divergent Dockerfile/base OS, not a sliding window. Scribe is same shape (archived 2.2, no 2.3 ever) - line name belongs in image name, not just tag. - -## Options for scribe - -### Option A - Rename to `scribe-2.2` (full alignment) - -- Changes: workflow L43-44 + L61, README L12, possibly `scribe-2.2/README.md` and `scribe-2.2/example/*` if any pull-URL refs -- Pros: consistent with 3/3 siblings; reserves `scribe` for hypothetical fork; alphabetical sort lines up; one rule to teach; future-proof -- Cons: breaks any existing `docker pull ghcr.io/tiennm99/scribe:2.2`; old GHCR + Docker Hub packages orphaned (inert) -- Blast radius: low. 7 weeks old, no known external consumers - -### Option B - Keep as `scribe` (document exception) - -- Pros: zero migration, no orphans, shorter name -- Cons: convention dies on first stress test; future contributors must memorize special case; irregular sort; retroactively ugly if `scribe-3.x` appears -- Blast radius: zero now, debt later - -### Option C - Dual-publish for transition - -- Pros: smoothest external transition -- Cons: doubles artifacts; sunset date easy to forget; complexity unjustified for a personal legacy archive -- Blast radius: medium - -### Option D - Drop suffix from all siblings (inverted) - -- Reject: breaks multi-major-line model; requires renaming 3 existing packages; strictly worse - -## Trade-off matrix - -| Dim | A (rename) | B (keep) | C (dual) | D (drop suffix) | -|---|---|---|---|---| -| Consistency | full | one outlier | during transition | inverted | -| Migration cost | low (~5 edits) | zero | low + ongoing | high (3 pkgs) | -| Orphans | 2 | 0 | 2 eventually | 6+ | -| Future-proof | yes | no | yes | no | -| Discoverability | alphabetical | irregular | irregular | alphabetical | -| Teach cost | 1 rule | 1 rule + exception | 1 rule + sunset | 1 worse rule | - -## Recommendation: Option A - rename to `scribe-2.2` - -- Package 7 weeks old, no known external consumers - blast radius minimal -- ~5 line edits, one workflow run -- Establishes rule cleanly on first stress test -- Orphan packages inert; deletable in 30 seconds via UI - -## `latest` tag policy - keep unchanged - -For write-once archived images, `latest` is semantically equivalent to canonical version tag. Usual objection ("silently shifts") doesn't apply - nothing shifts. Ergonomic default for casual `docker pull`. Edge case: CVE rebuild would shift latest, but consumers can pin to version tag. - -## Repo-wide rule to codify - -Add to `README.md` (new "Naming convention" section) and `CLAUDE.md`: - -``` -Naming convention for new images -- Subdirectory: - e.g. redis-3/, mongodb-3.6/ -- GHCR + Docker Hub image name: - (= subdir name) -- Workflow file: .github/workflows/publish--.yml -- Tags published: - - latest (alias for canonical/only version) - - e.g. 3.6.23, 7.4.5, 8u201 -- All three (subdir, image name, workflow basename) MUST match. -``` - -Rule: **subdir = image name = workflow basename**, all three derived from `-`. - -## Risks / considerations - -- Attestation `subject-name:` (L61) must also update - easy to miss -- Orphan packages harmless but visible in GHCR UI - decide: delete vs tombstone in README -- Grep `scribe-2.2/` for any `ghcr.io/tiennm99/scribe` literal before committing -- Commit message: `refactor(scribe): align image name with subdir naming convention` - -## Success metrics - -- `gh api /users/tiennm99/packages/container/scribe-2.2` returns 200 after first workflow run -- README image-index links resolve -- Naming-convention section exists in README, referenced from CLAUDE.md -- Next image added follows rule without prompting - -## Next steps - -1. User confirms Option A (or picks B/C) -2. If A: edit workflow + README + grep/fix any pull-URL refs in scribe-2.2/ -3. Codify naming rule in README + project CLAUDE.md -4. Decide on orphan deletion vs retention - -## Unresolved questions - -1. Delete orphaned `ghcr.io/tiennm99/scribe` + `docker.io/tiennm99/scribe` after rename, or tombstone in README? (Lean: delete.) -2. Does `scribe-2.2/example/docker-compose.yml` reference the published image, or only local build context? Quick grep needed before rename. -3. README image-index table shows GHCR only - add Docker Hub coords too? (Adjacent, out of scope.) -4. `gradle-8` / `oraclejdk-8` GHCR links missing from README (show `-`) - intentional pending first publish, or oversight? diff --git a/plans/reports/brainstorm-260528-1015-image-naming-convention-reframe-report.md b/plans/reports/brainstorm-260528-1015-image-naming-convention-reframe-report.md deleted file mode 100644 index fabb642..0000000 --- a/plans/reports/brainstorm-260528-1015-image-naming-convention-reframe-report.md +++ /dev/null @@ -1,128 +0,0 @@ -# Image Naming Convention - Re-brainstorm (A vs B, no scribe special-casing) - -## TL;DR - -**Recommend Convention A** (`-:`). Same conclusion as previous brainstorm, narrower reasoning. Single strongest argument: `latest` semantics break under B for archived software. - -## The two conventions - -| Convention | Image name | Tag | Example | Used by | -|---|---|---|---|---| -| A | `-` | `` | `couchbase-2.5:2.5.2` | 3 of 4 images in repo (current) | -| B | `` | `` | `couchbase:2.5.2` | scribe (current); Docker Hub officials (`python`, `redis`, `postgres`) | - -## Steel-mans - -### A — museum collection -Each major line is a write-once artifact: different upstream source, often different base OS, separate EOL/CVE story. Per-package `latest`, README, badge, attestation history. GHCR list IS the catalog. - -### B — library catalog -One package per service, tag namespace handles divergence (`3.11-bookworm`, `3.11-alpine`). Adding a new major line is `new subdir + new tag` instead of `new package`. Matches `docker pull python:3.11` muscle memory. - -## Where the choice actually matters - -### Adding Couchbase 6 hypothetically - -| Aspect | A | B | -|---|---|---| -| GHCR discoverability | 2 rows side-by-side | 1 row, tags hidden | -| README image-index table | grows linearly | stays narrow | -| GHCR package list | growing alphabetical | compact cluster | -| Workflow files | 1:1 with subdir | 1:1 subdir, but **multiple workflows push to same package** | -| Attestation `subject-name` | per-line lineage | mixed lineage | -| `latest` semantics | bounded per line | ambiguous - newest wins? meaningless? | -| Adding a build | heavyweight (new package) | lightweight (new tag) | - -### Multiple builds within one line (alpha/stable) -Tag suffixes work in both. Wash. - -### Base-OS divergence -Docker officials use tag suffixes (`python:3.11-alpine`). But that pattern is for SAME software on different runtimes. Here, `couchbase-2.5` (CentOS) vs `couchbase-6` (Ubuntu) is DIFFERENT software trees - more like `python` vs `pypy`. Analogy doesn't transfer. - -## `latest` tag - the decisive argument - -### Under A -`latest` per package = canonical build of that frozen line. Stable, bounded, doesn't drift across major lines. - -### Under B -- `couchbase:latest` = newest tag wins (Docker Hub default). User landing here for legacy 2.5 gets 6.6.0. **Misleading.** -- Fix: don't publish `latest` under B. Every README example must spell out a version tag. No quick-pull demo. -- Alternative: pin `latest` to a specific version. Which? "Oldest" is weird; "most-popular" needs telemetry; "last added" is arbitrary. - -A's `latest` is mildly defensible. B's `latest` is broken or must be dropped. Net point for A. - -## Workflow / CI - -- A: each workflow owns its package. Zero concurrency risk between major lines. -- B: multiple workflows push to same package on different tags. Tag uniqueness avoids data loss, but: - - `latest` pointer flaps if both publish `latest` (must disable on all but one) - - Attestation history mixes lines - harder to audit - - Concurrency groups need per-tag rescoping - -Net point for A. - -## Migration cost if B were chosen - -| File | Edit | -|---|---| -| 3x `publish-*.yml` (couchbase, gradle, oraclejdk) | strip `-` from `images:` and `subject-name:` | -| `publish-scribe-2.2.yml` | no change (already B-style) | -| `README.md` | image-index table + pull examples + package links | -| 4x `/README.md` | regrep for pull URLs | -| 4x `/example/*` | regrep for pull URLs | -| Tag policy | drop `latest` or pin per-service - new decision needed | -| GHCR + Docker Hub cleanup | 6 orphan packages | - -~12-15 edits + new tag-policy decision + 6 orphans + concurrency rescoping. **~3x cost of A-renames-scribe**, lands in worse place. - -A-route: ~5 edits, no tag-policy question, 2 orphans. - -## Why A wins (5 reasons) - -1. **`latest` breaks under B for archives.** Strongest argument. A's `latest` per-line is stable; B's is misleading or must be dropped. -2. **Attestation lineage per-line under A, mixed under B.** Matters for supply-chain trust on a repo whose whole point is "I built these, trust them". -3. **Docker-official analogy doesn't transfer.** Officials are sliding-window for maintained software; this repo is a museum of frozen artifacts. Different domain. -4. **Migration asymmetry.** Don't pay 3x to land in worse place. -5. **Per-line discoverability matches the artifact model.** Each exhibit gets its own plinth. GHCR package list IS the catalog. - -The one cost of A - divergence from Docker official conventions - is a feature here. Visitors are specifically looking for legacy software; seeing 4 distinct rows is more discoverable than one mystery `couchbase` with hidden tag list. - -## Codified rule - -``` -## Naming convention - -This repo packages archived/legacy software. Each major version line is a -write-once artifact with its own base OS, Dockerfile, attestation history, -and `latest` pointer. - -Rule: - Subdirectory : -/ - GHCR image : - - Docker Hub image : - - Workflow file : publish--.yml - Tags published : - - e.g. 2.5.2, 8.13, 8u201, 2.2 - - latest (alias for canonical build of THIS line) - -Constraint: - subdir == GHCR image == Docker Hub image == workflow basename. No exceptions. - -Why not :? - This repo is a museum, not a sliding window. `latest` per major line is - meaningful and stable. `latest` across a service would be misleading - (newest version wins, even when users came here specifically for the - archived line). Attestation lineage is also cleaner per line. - -New major line of an existing service? - New subdir, new workflow, new GHCR + Docker Hub package. Not a new tag - under the existing package. -``` - -## Unresolved questions - -1. `latest` on CVE rebuild - shifts digest. Document "pin by version tag for reproducibility"? -2. Orphan cleanup for `scribe` + `scribe:latest` - delete vs tombstone? (Lean: delete.) -3. Docker Hub coords in README image-index table - add column? (Defer until rename lands.) -4. `gradle-8` / `oraclejdk-8` GHCR links show `-` - pending first publish or never triggered? -5. Codified rule in README only, or README + CLAUDE.md? (Lean: both.) diff --git a/plans/reports/brainstorm-260528-1312-image-naming-final-verdict-report.md b/plans/reports/brainstorm-260528-1312-image-naming-final-verdict-report.md deleted file mode 100644 index f37e477..0000000 --- a/plans/reports/brainstorm-260528-1312-image-naming-final-verdict-report.md +++ /dev/null @@ -1,98 +0,0 @@ -# Image Naming Convention -- Final Verdict (Round 3) - -State verified 2026-05-28: - -- 2 images only: couchbase-2.5/, scribe-2.2/ (commit ff5e5f6 dropped gradle/oraclejdk) -- scribe carries OCI labels including image.title, image.licenses=Apache-2.0, image.source (commits afaa631 + 4ef7dfb). Couchbase does NOT. -- Workflow labels-block pattern proven in publish-scribe-2.2.yml L48-53. - -## Does new state alter the verdict? - -Two real changes: - -1. Sample collapsed to 2. Defend-the-convention frame is dead. 50/50 split = clean pick, no incumbent. -2. OCI image.title on scribe. Weakens ONE sub-argument (image-name-as-identifier) but does not touch the load-bearing one: latest semantics across major lines. docker inspect showing the title does not help a user typing docker pull -- they see the name, not labels, until after pull. - -Neither change reaches the Round-2 core argument: archived-software repo = museum, latest per major line is the only stable semantic. - -## Three options - -### Option A -- rename scribe to scribe-2.2 - -- Edits: workflow L43,44,67 (3); scribe-2.2/README.md (4); scribe-2.2/example/docker-compose.yml (1); root README.md L10 (1). ~9 mechanical edits. -- latest: stable per line. scribe-2.2:latest = canonical 2.2 build, always. -- New couchbase-6 later: new subdir, new workflow, new package. Trivial. No collision. -- Hypothetical scribe-3: new subdir scribe-3.x/, new package. Old scribe-2.2 untouched, no latest drift. -- Discoverability: GHCR list shows couchbase-2.5, scribe-2.2 side-by-side, alphabetical, lineage explicit. -- OCI label: complementary, not redundant. Name says which line; label says what it is. - -### Option B -- rename couchbase-2.5 to couchbase - -- Edits: workflow L43,44,61 (3); root README.md L9 link + L15 pull (2); couchbase-2.5/docker-compose.example.yml (1). ~6 edits + 1 orphan package. -- latest: BREAKS the moment couchbase-6 lands. couchbase:latest = newest-published = 6.x. User searching for 2.5 gets 6 silently. Must drop latest or pin awkwardly. -- New couchbase-6 later: same package, new tag 6.x.x. Cheap, but forces latest-policy reckoning. Two workflows pushing to one package -- tag uniqueness saves data but latest flaps. -- Hypothetical scribe-3: same story. Repeated problem. -- Discoverability: GHCR shows couchbase + scribe. Major lines hidden behind tag list. Docker-official muscle memory yes, but this is not sliding-window software. -- OCI label: helps identification post-pull, does NOT solve latest ambiguity pre-pull. - -### Option C -- codified asymmetry (lazy migration) - -- Rule: 1 line per service = service:version; more-than-1 line = rename to service-major:full lazily. -- Under C, today state = couchbase + scribe (B-shaped). Lazy migration = the painful B-to-A rename at the worst moment (adding new line under deadline). -- latest: works today, breaks at migration. -- Forces the most expensive migration (rename + orphan + consumer breakage) at the moment of highest cognitive load. Anti-KISS. - -## Verdict: Option A (unchanged from prior rounds) - -1. Decisive argument (latest stability across major lines for archived software) unchanged by both new state-changes. Sample size and OCI labels do not touch it. -2. OCI image.title is COMPLEMENTARY to the line-suffix name, not a substitute. Pull-time discoverability (docker search, GHCR URL, badge) happens before any inspect. -3. Migration cost asymmetry stays: A = ~9 edits, no latest-policy rewrite. B = ~6 edits + new latest policy + landmine for next major line + orphan. C = pay later, more, at worse time. -4. With only 2 images, A locks in the rule cheaply NOW. Cost of B later (when couchbase-6 arrives) is provably higher than A now. Asymmetric optionality favors A. -5. couchbase-2.5-is-the-lone-convention-follower framing reversible: scribe rename has cheaper blast radius (7-week-old workflow, 1 example-compose consumer, fresh package). Sunk-cost cuts against B, not A. - -## Codified rule (README + CLAUDE.md, copy-pasteable) - -``` -## Naming convention - -This repo packages archived/legacy software. Each major version line is a -write-once artifact with its own base OS, Dockerfile, attestation history, -and latest pointer. - -Naming rule (all four MUST match): - - Subdirectory : -/ - GHCR image : - - Docker Hub image : - - Workflow file : publish--.yml - -Examples: couchbase-2.5, scribe-2.2. Future: couchbase-6, redis-3. - -Tags published per image: - - - e.g. 2.5.2, 2.2, 8u201 - - latest alias for canonical build of THIS major line - -Adding a new major line of an existing service = new subdir + new workflow -+ new package. NOT a new tag under the existing package. Keeps latest -semantics stable per line and attestation lineage clean. - -OCI image-spec labels (org.opencontainers.image.*) REQUIRED on every image -for metadata-level identification independent of name. See -scribe-2.2/Dockerfile for the canonical set. -``` - -## Migration order if A approved - -1. Rename literals in scribe (9 edits above). -2. Push, verify GHCR package scribe-2.2 populates with latest + 2.2. -3. Delete orphan ghcr.io/tiennm99/scribe + Docker Hub tiennm99/scribe via UI. -4. Add naming-convention section to root README.md + project-local CLAUDE.md. -5. Separate task: port OCI labels to couchbase using the labels: pattern from publish-scribe-2.2.yml L48-53. - -## Unresolved questions - -1. Orphan ghcr.io/tiennm99/scribe after rename -- delete or tombstone? Lean delete (7 weeks old). -2. Pre-check Docker Hub docker.io/tiennm99/scribe-2.2 namespace availability before rename push? Trivial check, do it. -3. CLAUDE.md scope: user-global vs project-local. Convention belongs in project-local D:/tiennm99/docker-images/CLAUDE.md (create if absent). Confirm. -4. OCI labels on couchbase -- same task as rename, or separate? Lean separate to keep rename diff minimal. diff --git a/plans/reports/code-review-260528-0925-scribe-cleanup-verification-report.md b/plans/reports/code-review-260528-0925-scribe-cleanup-verification-report.md deleted file mode 100644 index 6b49707..0000000 --- a/plans/reports/code-review-260528-0925-scribe-cleanup-verification-report.md +++ /dev/null @@ -1,141 +0,0 @@ -# Scribe-2.2 Cleanup Verification Review - -**Date:** 2026-05-28 -**Scope:** Uncommitted changes in `scribe-2.2/` vs HEAD -**Reviewer:** code-reviewer - -## Files Reviewed - -- `scribe-2.2/Dockerfile` -- `scribe-2.2/README.md` -- `scribe-2.2/config/scribe.conf` -- `scribe-2.2/example/README.md` -- `scribe-2.2/example/docker-compose.yml` -- `scribe-2.2/example/sender/main.go` -- `scribe-2.2/scripts/docker-entrypoint.sh` - -## Overall Assessment - -Pure cosmetic cleanup. No functional regressions. All build steps, runtime behavior, ports, volumes, users, configs unchanged. One concern: removed metadata LABELs. - -## Critical Issues - -None. - -## High Priority - -None. - -## Medium Priority — Concerns (do not auto-revert) - -### C1. Removed LABEL metadata in runtime stage - -- HEAD had: `LABEL maintainer`, `LABEL description`, `LABEL version="2.2"` -- Working tree keeps only `LABEL maintainer` -- `description` and `version` labels removed -- Impact: - - `docker inspect scribe:2.2` no longer reports version/description - - Image registries (Harbor, GHCR) lose searchable description - - Image scanners / SBOM tools lose declared version field - - `org.opencontainers.image.version` / `.description` were not used (only plain `version`/`description`), so OCI compliance was already partial -- Status: **flag as intentional-or-regression question for user**. Image tag (`scribe:2.2`) still encodes the version, so loss is minor. But `description` had documentation value -- Recommended (if user wants to re-add): use OCI-standard labels: - - `org.opencontainers.image.version="2.2"` - - `org.opencontainers.image.description="Facebook Legacy Scribe - real-time log aggregation daemon"` - - `org.opencontainers.image.source="https://github.com/facebookarchive/scribe"` - -## Low Priority - -None. - -## Per-Question Verification - -### 1. Dockerfile build steps & package list - -- **Build steps:** no removals/alterations. Only banner-comment lines and inline `# ──` comments removed. All RUN blocks identical -- **Builder yum list:** same 14 packages, sorted alphabetically: - - HEAD: `gcc, gcc-c++, make, autoconf, automake, libtool, git, wget, flex, bison, boost-devel, libevent-devel, openssl-devel, zlib-devel` (14) - - Working: `autoconf, automake, bison, boost-devel, flex, gcc, gcc-c++, git, libevent-devel, libtool, make, openssl-devel, wget, zlib-devel` (14) - - Set-equal, count-equal. One-package-per-line improves readability -- **Runtime yum list:** unchanged (boost-filesystem, boost-system, boost-thread, libevent, openssl) -- **EXPOSE 1463, USER scribe, VOLUME, ENTRYPOINT:** all unchanged - -### 2. Removed LABELs - -- `LABEL maintainer="Tien Nguyen Minh "` still present -- `LABEL description=...` and `LABEL version="2.2"` removed -- See C1 above. Flagged, not auto-reverted - -### 3. Go file `example/sender/main.go` - -Four diff hunks, all non-logic: -- L5 (file header comment): em-dash to hyphen -- L125 comment: `messageBegin — detect` to `messageBegin: detect` -- L161 comment: `no return field present → treat as OK` to `no return field present; treat as OK` -- L211 string literal (user-visible): `Hello from Go sender — message %d/%d` to `Hello from Go sender - message %d/%d` - -No logic touched. No control flow, no struct fields, no Thrift wire-encoding bytes, no retry logic, no timeouts changed. - -**README sync check:** `example/README.md:41` already updated to `Hello from Go sender - message N/5`. Consistent with main.go output. Confirmed via grep — only the two expected occurrences exist, both hyphen. - -### 4. `config/scribe.conf` - -Only comment formatting: -- L1 header em-dash to hyphen -- 4 section-header `# ── Name ──────` lines simplified to `# Name` - -Directives unchanged: `port=1463`, `max_msg_per_second=100000`, `max_msg_size=16777216`, `check_interval=3`, default store block (file, /var/log/scribe, hourly rotation, write_meta=true). No store directive added/removed. - -### 5. Em-dash semantic breakage - -Reviewed all em-dash to hyphen and em-dash to `:`/`;` replacements: - -- `example/README.md:51` `Message category → log subdirectory name` to `Message category to log subdirectory name` — arrow replaced with "to". Reads naturally -- `example/README.md:62` `[link] — see the [other link]` to `[link] - see the [other link]` — fine -- `main.go:161` `→ treat as OK` to `; treat as OK` — semantically equivalent (consequence vs sequence). OK -- `main.go:125` `messageBegin — detect` to `messageBegin: detect` — annotation style. OK -- All other em-dash to hyphen replacements are parenthetical-aside style. No semantic loss - -No broken Markdown links, no broken Mermaid/code-fence boundaries. - -### 6. Residual Unicode - -Grep for `[‐-―─-╿‘’“”…←-↓]` across all of `scribe-2.2/`: **0 matches**. Cleanup is complete. - -Also grep for `→ — – ─ │ ┌ └ ├ ┤`: **0 matches** in any of the 7 modified files. - -## Positive Observations - -- Alphabetized yum package list improves diff readability for future deps changes -- One-package-per-line aids future bisect of build failures -- ASCII-only sources improve grep/sed/IDE tooling on Windows where Unicode rendering varies -- Go string literal change keeps user-visible message ASCII — safer for log-grepping pipelines downstream -- No commit yet, so easy to fold back C1 if user agrees - -## Trust-Boundary / Security Review - -- No auth changes, no input validation paths touched -- No new env vars, no new ports, no new file paths -- Non-root `scribe` user retained -- No new ADD/COPY from external sources -- No secrets in diff - -## Metrics - -- Files changed: 7 -- Lines net: comment/whitespace-only delta -- Functional code changes: 0 -- Logic changes: 0 -- Build-graph changes: 0 -- Removed metadata labels: 2 - -## Recommended Actions - -1. Decide on C1 (LABEL description/version removal): - - **Keep removed** — accept minor metadata loss - - **Re-add** — preferably as OCI-standard `org.opencontainers.image.*` labels -2. If C1 accepted as-is, commit cleanup as `style(scribe): normalize ASCII formatting in scribe-2.2/` - -## Unresolved Questions - -1. Was removal of `LABEL description` and `LABEL version` intentional, or collateral damage during banner-comment cleanup? Image tag still carries version, so functional impact is nil, but discoverability via `docker inspect` is lost. diff --git a/plans/reports/code-review-260528-1221-scribe-oci-labels-and-cleanup-report.md b/plans/reports/code-review-260528-1221-scribe-oci-labels-and-cleanup-report.md deleted file mode 100644 index 2289b13..0000000 --- a/plans/reports/code-review-260528-1221-scribe-oci-labels-and-cleanup-report.md +++ /dev/null @@ -1,95 +0,0 @@ -# Code Review: scribe-2.2 OCI labels + cleanup verification - -**Date:** 2026-05-28 -**Scope:** uncommitted `scribe-2.2/` changes vs HEAD (`ff5e5f6`) -**Focus:** OCI label re-addition delta (cleanup already cleared in `code-review-260528-0925-scribe-cleanup-verification-report.md`) - -## Scope -- Files changed: 7 (Dockerfile, README, config/scribe.conf, example/README, example/docker-compose.yml, example/sender/main.go, scripts/docker-entrypoint.sh) -- LOC: +38 / -57 -- Delta under review: 3 `LABEL org.opencontainers.image.*` lines at Dockerfile:71-73 - -## Overall Assessment -Clean. OCI label addition is correct, well-formed, properly placed. Cleanup portion unchanged from prior approval. Ready to commit. - -## OCI Label Verification - -### Key names — all spec-compliant -Verified against https://github.com/opencontainers/image-spec/blob/main/annotations.md: -- `org.opencontainers.image.version` — OK, "version of the packaged software" -- `org.opencontainers.image.description` — OK, "human-readable description" -- `org.opencontainers.image.source` — OK, "URL to get source code" - -### Values — well-formed -- `"2.2"` — plain ASCII string, OK -- `"Facebook Legacy Scribe - real-time log aggregation daemon"` — ASCII hyphen (was `–` U+2013 before cleanup), no smart quotes, no escaping issues -- `"https://github.com/facebookarchive/scribe"` — HTTP 200 verified, sane - -### Placement — correct -Dockerfile:68-73 — runtime stage (`FROM centos:7`), after `LABEL maintainer`. Builder stage correctly left unlabeled (only runtime image gets metadata). - -## Optional OCI labels worth considering (NOT auto-added) - -Recommendations only — user decides: - -| Label | Suggested value | Rationale | -|-------|----------------|-----------| -| `image.title` | `"Facebook Legacy Scribe"` | Short human-readable name, complements description. Most-commonly-used OCI label after version. Worth adding. | -| `image.licenses` | `"Apache-2.0"` | Scribe's license (SPDX expression). Useful for downstream consumers / compliance scans. Worth adding. | -| `image.url` | could point to this repo or README | Marginal value since `image.source` already covers provenance. Skip unless you want to distinguish "where to learn" from "where the source lives". | -| `image.revision` | scribe upstream git SHA at build time | Scribe is `--depth 1` cloned (Dockerfile:60) → revision drifts silently between rebuilds. Pinning would need a build ARG. Defer; not blocker. | -| `image.created` | RFC 3339 timestamp | BuildKit auto-injects this; manual labeling not needed. | -| `image.vendor` | `"tiennm99"` or org | Optional, marginal. Skip. | - -**Strongest recommendation:** add `image.title` + `image.licenses`. The other four are skippable for an archive image. - -## Diff Drift Check -Confirmed: full scribe-2.2 diff = (previously approved cleanup) + (3 OCI labels). No unintended edits. - -Per-file: -- **Dockerfile** — cleanup (box-drawing comments, alpha-sorted builder deps, en-dash → hyphen) + OCI label swap. Clean. -- **README.md** — 2 en-dash → hyphen (cleanup). Clean. -- **config/scribe.conf** — 6 box-drawing/en-dash → ASCII (cleanup). Clean. -- **example/README.md** — 8 en-dash → hyphen (cleanup). Clean. -- **example/docker-compose.yml** — 1 en-dash → colon (cleanup). Clean. -- **example/sender/main.go** — 4 en-dash → hyphen/semicolon (cleanup, includes user-visible string `Hello from Go sender - message N/5`). Clean. -- **scripts/docker-entrypoint.sh** — 1 en-dash → hyphen (cleanup). Clean. - -No new files. No deletions. No file moves. - -## Critical Issues -None. - -## High Priority -None. - -## Medium Priority -None blocking. See "Optional OCI labels" above for incremental improvement. - -## Low Priority -- CRLF warnings from git (LF will be replaced by CRLF on Windows checkout). Pre-existing repo behavior, not a delta concern. - -## Positive Observations -- Migrated from non-standard `LABEL description` / `LABEL version` to OCI-standard keys — proper fix to the prior concern. -- All ASCII; no Unicode dashes carried over from cleanup pass into label values. -- Single-line `LABEL` per key (readable; multi-line continuation would also be fine, current style is clearer). -- `image.source` URL matches the actual upstream cloned at Dockerfile:60 (`https://github.com/facebookarchive/scribe.git`) — consistent. - -## Recommended Actions -1. **Ship as-is** — no blockers. -2. *(Optional, recommend)* — add two more OCI labels before committing: - ```dockerfile - LABEL org.opencontainers.image.title="Facebook Legacy Scribe" - LABEL org.opencontainers.image.licenses="Apache-2.0" - ``` - Confirm Scribe upstream license is Apache-2.0 first (facebookarchive/scribe LICENSE file). - -## Metrics -- OCI spec conformance: 3/3 keys valid -- Label value well-formedness: pass -- Source URL reachability: HTTP 200 -- Drift beyond approved cleanup: zero - -## Unresolved Questions -- Do you want to add `image.title` + `image.licenses` now, or ship the minimal 3-label set? (Recommend adding both; trivial extra metadata.) -- Confirm Scribe upstream license = Apache-2.0 before setting `image.licenses` (worth a 5s check at https://github.com/facebookarchive/scribe/blob/master/LICENSE). diff --git a/plans/reports/researcher-260528-1221-scribe-oci-labels-license-verification-report.md b/plans/reports/researcher-260528-1221-scribe-oci-labels-license-verification-report.md deleted file mode 100644 index 754a283..0000000 --- a/plans/reports/researcher-260528-1221-scribe-oci-labels-license-verification-report.md +++ /dev/null @@ -1,61 +0,0 @@ -# Scribe OCI Image Labels — License & Metadata Verification - -## Q1: License Identifier & Multi-License Analysis - -**Finding: SPDX identifier is `Apache-2.0` (single license).** - -### Evidence -- **Scribe upstream:** https://github.com/facebookarchive/scribe — Licensed under Apache License 2.0 (verified via LICENSE file). -- **SPDX value:** `Apache-2.0` -- **Quote:** "Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License." - -### Multi-License Check (Thrift Dependency) -Dockerfile explicitly builds Apache Thrift 0.9.1 (line 28). Thrift is also Apache-2.0 licensed. - -**Conclusion:** No additional license expression needed. Both Scribe and bundled Thrift are Apache-2.0. SPDX label value: -``` -LABEL org.opencontainers.image.licenses="Apache-2.0" -``` - -Not required to use SPDX expression (`Apache-2.0 AND Apache-2.0`) — single `Apache-2.0` is correct. - ---- - -## Q2: Additional OCI Image Annotations — Recommendation Table - -| Label | Recommend? | Reason | -|-------|------------|--------| -| `image.title` | **YES** | Short human-readable name; trivial to add. E.g., `"Scribe Log Aggregation Daemon"` | -| `image.url` | NO | Project is archived (read-only); homepage is same as `image.source`. Redundant. | -| `image.documentation` | NO | No maintained docs site. README is in archived repo — already discoverable via `image.source`. Skip. | -| `image.vendor` | NO | Original author (Facebook) no longer maintains. Current maintainer is builder (you). Not load-bearing for legacy image. Skip. | -| `image.authors` | **MAYBE** | If you want attribution, add `"Tien Nguyen Minh"` (matches Dockerfile maintainer). Otherwise skip — not critical for archived image. | -| `image.created` | **YES** | Build timestamp is meaningful for reproducibility. Add via `--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')` at build time. | -| `image.revision` | NO | Dockerfile uses `git clone --depth 1` (line 58), losing commit history. Revision would be stale/misleading. Skip unless build args fix the clone depth. | - ---- - -## Recommended Additions (Final Label Set) - -```dockerfile -# Add these two lines to the LABEL block (lines 71-73) -LABEL org.opencontainers.image.title="Scribe Log Aggregation Daemon" -LABEL org.opencontainers.image.licenses="Apache-2.0" -LABEL org.opencontainers.image.created="${BUILD_DATE}" -``` - -Optional (low priority): -```dockerfile -LABEL org.opencontainers.image.authors="Tien Nguyen Minh " -``` - -Build command to inject BUILD_DATE: -```bash -docker build --build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" -t scribe:2.2 . -``` - ---- - -## Unresolved Questions - -None. License is clear (Apache-2.0), dependency check complete, and OCI spec is authoritative. diff --git a/plans/reports/researcher-260528-1324-couchbase-license-and-source-verification-report.md b/plans/reports/researcher-260528-1324-couchbase-license-and-source-verification-report.md deleted file mode 100644 index 8c8adf7..0000000 --- a/plans/reports/researcher-260528-1324-couchbase-license-and-source-verification-report.md +++ /dev/null @@ -1,29 +0,0 @@ -# Couchbase 2.5 License & Source Verification - -## Q1: License (SPDX Identifier) - -**Finding:** `Apache-2.0` - -**Evidence:** Wikipedia: "Couchbase Server is a packaged version of Couchbase's open source software technology and is available in a community edition without recent bug fixes with an Apache 2.0 license" ([Couchbase Server - Wikipedia](https://en.wikipedia.org/wiki/Couchbase_Server)). Couchbase Server 2.0 released Dec 2012; v2.5.2 inherits same Apache 2.0 license applied since open-source inception (2011, post Membase/CouchOne merger). - -**SPDX ID:** `Apache-2.0` - -No mixing of licenses in Server 2.5.x; only one license applies to the binary. - ---- - -## Q2: `image.source` URL - -**Recommendation:** `https://github.com/couchbase/docker` - -**One-line reason:** General upstream repo URL maximizes durability; pinned commit hashes are infrastructure detail, not user-facing metadata. - -**Alternatives rejected:** -- Pinned branch URLs (`…/tree/14f9e5f37…`) — commit references rot when branches are deleted or rebased; violates OCI-label durability principle (user should find repo, not fight dead links). -- Scribe precedent uses `https://github.com/facebookarchive/scribe` (upstream source root), not a pinned archive commit, so Couchbase should match that pattern. - ---- - -## Unresolved Questions - -None. Both values verified via public sources. diff --git a/plans/reports/tester-260528-0925-scribe-cleanup-verification-report.md b/plans/reports/tester-260528-0925-scribe-cleanup-verification-report.md deleted file mode 100644 index c323ca8..0000000 --- a/plans/reports/tester-260528-0925-scribe-cleanup-verification-report.md +++ /dev/null @@ -1,94 +0,0 @@ -# Scribe-2.2 Cleanup Verification Report - -**Date:** 2026-05-28 -**Scope:** Cosmetic cleanup of Dockerfile, docker-compose.yml, and Go sender (em-dash → ASCII conversions) -**Status:** PASS — All checks successful. No regressions detected. - ---- - -## Check 1: Go Sender Compile Verification - -**Command:** -```bash -cd scribe-2.2/example/sender -go vet . -go build . -``` - -**Result:** ✓ PASS -- `go vet`: No issues reported -- `go build`: Compiled successfully to `scribe-example-sender.exe` (3.5 MB) -- No syntax errors, no dead code warnings - ---- - -## Check 2: docker-compose.yml Syntax - -**Command:** -```bash -docker compose -f scribe-2.2/example/docker-compose.yml config -``` - -**Result:** ✓ PASS -- Config validated and expanded successfully -- Services: `scribe` (using `ghcr.io/tiennm99/scribe:2.2`), `sender` (build from `./sender`) -- Environment variables correctly set: `SCRIBE_HOST=scribe`, `SCRIBE_PORT=1463`, `SCRIBE_COUNT=5` -- Volumes and depends_on constraints resolved correctly -- No syntax errors - ---- - -## Check 3: Dockerfile Build (Skipped) - -**Rationale:** Per instruction, skipped full `docker build` to avoid slow/brittle CentOS vault pull and multi-stage Thrift+Scribe compilation. - -**Changes Reviewed:** -- Cosmetic comment reformatting: em-dashes → ASCII, ASCII arrows → ASCII -- No build-step logic changed -- Removed redundant LABEL fields (description, version) — no functional impact - ---- - -## Check 4: Output String Verification - -**File:** `scribe-2.2/example/sender/main.go` line 211 - -**Expected (per README):** -``` -Hello from Go sender - message N/5 -``` - -**Actual (post-cleanup):** -```go -fmt.Sprintf("Hello from Go sender - message %d/%d", i, count) -``` - -**Result:** ✓ MATCH -The em-dash `—` was converted to ASCII hyphen `-`. Format matches README claim exactly. -When `count=5` and loop runs `i=1..5`, output will be: -- `Hello from Go sender - message 1/5` -- `Hello from Go sender - message 2/5` -- ... (5 total) - ---- - -## Summary - -| Component | Status | Notes | -|-----------|--------|-------| -| Go sender (vet + build) | ✓ PASS | Binary compiles, no warnings | -| docker-compose.yml | ✓ PASS | Syntax valid, env vars & volumes correct | -| Dockerfile | ⊘ SKIPPED | Changes are cosmetic only; build step skipped per instruction | -| Output format | ✓ MATCH | Message string aligns with README | - ---- - -## Verdict - -**No regressions detected.** The cleanup is purely cosmetic (em-dash → ASCII character conversions in comments and one log-message string). The Go sender will compile and run identically, and the compose stack will deploy as before. - ---- - -## Unresolved Questions - -None. All checks complete and passing.