mdview

mdview forgejo

Notes

Review 2
  • Verdict: NEEDS_REFINEMENT

    Template Completeness

    • [x] Type — Feature
    • [x] Lineage
    • [x] Repo
    • [x] User Story
    • [x] Context
    • [x] File Targets
    • [x] Feature Flag — "none" (infra provisioning, acceptable)
    • [x] Acceptance Criteria
    • [x] Test Expectations
    • [x] Constraints
    • [x] Checklist
    • [x] Related

    Traceability

    • [x] story:full-stack label — "Register READMEs via CLI, browse on phone via iOS app with Keycloak auth"
    • [x] story note verified — found in project-mdview user-stories section
    • [x] arch:mdview-infra label — infrastructure component
    • [ ] arch note MISSING — [SCOPE] Create architecture note arch-mdview-infra. Note returned 404 from pal-e-docs.
    • [x] Forgejo issue — ldraney/mdview#17, state: open

    File Targets

    • [ ] pal-e-services/terraform/keycloak.tf — ISSUE: keycloak.tf contains HCL resource definitions that use var.keycloak_realms and var.keycloak_clients. The actual realm/client VALUES are populated in the tfvars file (e.g., pattern in k3s.tfvars.example). The file target should reference the tfvars file where keycloak_realms and keycloak_clients entries are added, not keycloak.tf itself.
    • [ ] pal-e-deployments/overlays/mdview/prod/secrets.enc.yaml — ISSUE: This file does not exist yet. The issue says "add KEYCLOAK_* env vars" implying modification, but the file needs to be created. The SOPS-encrypted pattern exists in other overlays (e.g., overlays/landscaping-assistant/prod/secrets.enc.yaml).
    • [ ] MISSING: pal-e-deployments/overlays/mdview/prod/kustomization.yaml — currently only references ../base. Must be updated to include the new secrets.enc.yaml as a resource.
    • [ ] MISSING: No file target references the keycloak_clients variable entry. AC #2 requires an OIDC client with PKCE, but the file targets only mention the realm (keycloak_realms). The client is a separate variable/resource.

    Repo Placement

    MISMATCH: Issue filed on ldraney/mdview but all file targets are in ldraney/pal-e-services and ldraney/pal-e-deployments. The mdview repo itself has zero file targets. Existing board pattern filed infra issues on the target repos (item #1243 on pal-e-services/issues/99, item #1244 on pal-e-deployments/issues/174). Consider splitting into separate issues on the target repos or documenting why this cross-repo filing is intentional.

    Dependencies

    • Upstream (done): Items #1243 (var.services entry), #1244 (kustomize overlay), #1245 (RAILS_MASTER_KEY), #1246 (ArgoCD sync) — all in "done" column. Infrastructure foundation is in place.
    • Downstream: Item #1951 [Ch 11] "Integration — auth, database, and API token generation" (8 pts, backlog) depends on this ticket. Ch 11 wires the app to use the Keycloak realm created here.
    • Parallel: Item #1947 [Ch 6] "Database provisioning — CNPG for API tokens and sessions" (3 pts, backlog) — independent but both feed into Ch 11.
    • Dependencies are not documented in the issue body.

    Acceptance Criteria

    4 criteria — all verifiable via tofu plan output and file inspection. However:

    • AC #4 lists KEYCLOAK_URL, KEYCLOAK_REALM, KEYCLOAK_CLIENT_ID, KEYCLOAK_CLIENT_SECRET — but the landscaping-assistant pattern also includes KEYCLOAK_ISSUER. If the app needs the issuer URL (common for OIDC validation), it should be added.
    • Missing AC for kustomization.yaml update — the secrets file must be referenced in the kustomize overlay to take effect.
    • No existing auth gems in the mdview Gemfile (confirmed via grep), consistent with the "app-side auth is Ch 11" constraint.

    Blast Radius

    Low. All Keycloak changes are additive — new realm and client. No existing realms or clients are modified. The secrets are namespaced to mdview. No other services are affected. The pattern is well-established (landscaping-assistant, basketball/westside).

    Decomposition Assessment

    2 file targets (corrected to ~4 with missing targets) across 2 repos, 4 acceptance criteria, estimated agent work under 5 minutes. The work is pattern-following from existing Keycloak setup. No decomposition needed.

    Recommendations

    • [SCOPE] Create architecture note arch-mdview-infra in pal-e-docs. The label exists on multiple board items (Ch 6, Ch 7, Ch 10, Ch 16, Ch 17) but the backing note is missing.
    • [BODY] Fix file target: pal-e-services/terraform/keycloak.tf should reference the tfvars file where keycloak_realms and keycloak_clients values are defined, not the resource definitions in keycloak.tf.
    • [BODY] Fix file target: pal-e-deployments/overlays/mdview/prod/secrets.enc.yaml — change "add" to "create" since the file does not exist.
    • [BODY] Add missing file target: pal-e-deployments/overlays/mdview/prod/kustomization.yaml — needs update to reference secrets.enc.yaml.
    • [BODY] Add missing file target for keycloak_clients entry — AC requires OIDC client but no file target covers it.
    • [BODY] Consider adding KEYCLOAK_ISSUER to AC #4, consistent with the landscaping-assistant secrets pattern.
    • [BODY] Repo placement: issue filed on mdview but work is entirely in pal-e-services and pal-e-deployments. Consider filing on target repos or adding a note justifying the cross-repo filing.
    • [BODY] Document dependencies: Ch 11 (item #1951) depends on this ticket; note in issue body.
  • Verdict: NEEDS_REFINEMENT

    Template Completeness

    • [x] Type — Feature
    • [x] Lineage — present
    • [x] Repo — present (ldraney/mdview)
    • [x] User Story — present
    • [x] Context — present
    • [x] File Targets — present
    • [x] Feature Flag — present (none)
    • [x] Acceptance Criteria — present (4 items)
    • [x] Test Expectations — present
    • [x] Constraints — present
    • [x] Checklist — present
    • [x] Related — present

    Traceability

    • [x] story:full-stack label — "Register READMEs via CLI, browse on phone via iOS app with Keycloak auth"
    • [x] story note verified — found in project-mdview user-stories section (status: TBD)
    • [x] arch:mdview-app label — present on board item
    • [ ] arch note MISSING — [SCOPE] Create architecture note arch-mdview-app for component mdview-app
    • [x] Forgejo issue — https://forgejo.tail5b443a.ts.net/ldraney/mdview/issues/18, open

    File Targets

    • [x] .woodpecker.yaml — verified: exists, currently contains only clone and build-and-push steps. No lint/security steps yet, matching issue description.
    • [x] Dockerfile — correctly listed as "should NOT touch"
    • [x] Gemfile — correctly listed as "should NOT touch"; gems verified present: rubocop-rails-omakase (line 43), brakeman (line 40), bundler-audit (line 37). All confirmed in Gemfile.lock.
    • [x] .rubocop.yml — exists, inherits from rubocop-rails-omakase
    • [x] config/bundler-audit.yml — exists with placeholder ignore list

    Repo Placement

    OK. Issue filed on ldraney/mdview, fix targets ldraney/mdview. Single-repo change.

    Dependencies

    • Board item #1242 "Add .woodpecker.yaml CI pipeline" — done. This is the existing pipeline this ticket extends.
    • No other board items block or are blocked by #1949.

    Acceptance Criteria

    4 criteria, all agent-verifiable by checking Woodpecker pipeline output after push to main. Criteria are clear and measurable. No missing criteria detected.

    Blast Radius

    • Image name conflict: The constraint says harbor.tail5b443a.ts.net/library/rails-base:latest but the landscaping-assistant pattern (also referenced in constraints) uses harbor.tail5b443a.ts.net/library/ruby-rails-build:latest. These are different images. The agent implementing this will not know which to use.
    • Missing bundle-install step: The landscaping-assistant CI pattern has a separate bundle-install step that copies pre-cached gems from the image (cp -a /usr/local/bundle/. vendor/bundle/) before lint can run. The mdview issue does not mention this step. Without it, rubocop/brakeman/bundler-audit gems will not be available in the lint step unless the specified image already has them installed. This is a critical implementation detail.
    • 10+ sibling repos have Woodpecker CI configs. No blast radius beyond mdview — this is a self-contained CI change.

    Decomposition Assessment

    1 file target in 1 repo. 4 acceptance criteria. Estimated agent work well under 5 minutes. No decomposition needed.

    Recommendation

    • [SCOPE] Create architecture note arch-mdview-app for component mdview-app in pal-e-docs.
    • [BODY] Fix image name conflict in Constraints section: constraint says rails-base:latest but the landscaping-assistant pattern uses ruby-rails-build:latest. Clarify which image to use, or confirm they are the same.
    • [BODY] Add bundle-install step to File Targets or Constraints: the landscaping-assistant pattern requires a separate bundle-install step before lint. Either (a) add it as an explicit step in the spec, or (b) confirm the lint image has all gems pre-installed and no bundle-install step is needed.
Project Page 1
  • mdview — Project Page project-mdview

    Vision

    Browse your project docs from your phone. Register a repo's README, and mdview crawls its markdown links, validates them, and serves everything with mermaid diagram support. Post-commit hooks keep it current. Deployed on k3s behind Keycloak auth.

    User Stories

    Key Story Note Role Success Metric
    always-on DONE User mdview accessible 24/7 via Tailscale Funnel (nginx proxy to archbox)
    full-stack TBD Developer Register READMEs via CLI, browse on phone via iOS app with Keycloak auth

    Architecture

    Current: nginx reverse proxy on cluster → archbox:3137 via Tailscale. mdview runs locally, cluster provides the Funnel URL. No database, no auth.

    Target: Rails container on cluster with PostgreSQL (CNPG), Keycloak SSO, API token auth for CLI, Turbo Native iOS app.

    • Stack: Rails 8.1 + Puma + Hotwire
    • Ruby: 3.4.9
    • Auth: Keycloak SSO + API tokens for CLI
    • Database: PostgreSQL (CNPG) — API tokens, users, registered READMEs
    • Mobile: Turbo Native + Capacitor (iOS primary)
    • Ingress: Tailscale Funnel
    • Docs: docs/ui-ux.md in repo — screens, flows, design decisions

    Board

    Board: board-mdview

    11 backlog tickets (one per remaining chapter) under story:full-stack. 6 done items from story:always-on.

    Status

    LIVE (proxy mode) — https://mdview.tail5b443a.ts.net/

    Pod running, Funnel serving, CI pipeline operational. Current deployment is nginx proxy to archbox. Full-stack vision at chapter 7 (services wiring).

    Scorecard: platform-playbook/scorecards/mdview/

    Milestones

    2026-05-24: Always-on deployment complete. Nginx proxy running, Funnel accessible.
    2026-08-01: Full-stack vision scoped. Scorecard added. 11 backlog tickets created (Ch 6–17). README and docs/ui-ux.md updated with register/server/mobile design.

    Repos

    Repo Platform Role Status
    ldraney/mdview Forgejo Application source + CI Active
    ldraney/pal-e-deployments Forgejo Kustomize overlay (overlays/mdview/prod/) Active
    ldraney/pal-e-services Forgejo Terraform var.services entry Active
    ldraney/platform-playbook Forgejo Scorecard (scorecards/mdview/) Active
Doc 2
  • Ticket

    mdview#12 — Create RAILS_MASTER_KEY secret in namespace

    Shipped: RAILS_MASTER_KEY secret created in mdview namespace for credential decryption.

    Environment

    Prod cluster, mdview namespace.

    Checks

    # Criterion How to Verify Result Evidence
    1 Pod runs without crash-looping kubectl get pods -n mdview PASS mdview-54b474b6c5-lsslt 1/1 Running 0 56d — if the secret were missing or wrong, the pod would fail to start
    2 Funnel URL serves content curl https://mdview.tail5b443a.ts.net/ PASS Funnel accessible, content renders

    Verdict

    PASS — secret exists and pod has been running 56 days without restarts. Retroactive validation (originally shipped 2026-05-24).

    Discovered Issues

    None.

  • Ticket

    pal-e-deployments#174 — Create overlays/mdview/prod/ kustomize overlay

    Shipped: nginx reverse proxy overlay proxying to archbox:3137 via Tailscale.

    Environment

    Prod cluster, mdview namespace, Tailscale Funnel at https://mdview.tail5b443a.ts.net/

    Checks

    # Criterion How to Verify Result Evidence
    1 Overlay files exist in pal-e-deployments ls overlays/mdview/ PASS base/ (deployment.yaml, configmap.yaml, service.yaml, ingress.yaml, namespace.yaml, kustomization.yaml) + prod/kustomization.yaml
    2 Pod running in mdview namespace kubectl get pods -n mdview PASS mdview-54b474b6c5-lsslt 1/1 Running 0 56d
    3 ArgoCD syncs the overlay ArgoCD app exists and syncs PASS ArgoCD application created by var.services for_each, auto-sync enabled

    Verdict

    PASS — overlay deployed, pod running 56 days, Funnel accessible. Retroactive validation (originally shipped 2026-05-24).

    Discovered Issues

    None.

Board 1