Operations

Workflows

CI evidence is phase-scoped: use the `build` profile for built-route evidence, `browser-verify` after browser verification (and its bounded PR review artifact when applicable), `preview` after screenshot evidence, and `l

Source
docs/workflows.md
Mode
rendered markdown

Workflows

Local development


npm run validate:all

npm run build:portal

npm run setup:preview-evidence

npm run validate:preview-evidence

npm run ci:local

CI evidence is phase-scoped: use the build profile for built-route evidence, browser-verify after browser verification (and its bounded PR review artifact when applicable), preview after screenshot evidence, and local only after the complete locally generated set. Browser verification and preview evidence are independent CI jobs; neither profile accepts the other job's report.

Source mirror workflow

The Confluence mirror foundation is present as a local fixture and contract set. Mirror tooling should write immutable source artifacts under confluence/ and create a sync report under confluence/sync-runs/.


npm run validate:confluence-mirror

Live sync remains approval-gated. Before a real snapshot run is committed, review credential handling, RWS content classification, retention, preview exposure, attachment policy, and publication boundaries. Synthetic fixtures must remain marked mode: fixture.

Scoped sync and offline freshness

The bounded sync command is intentionally two-phase. A normal command runs the approved credentialed read-only probe, verifies the resulting local report, and writes report evidence only; it does not modify the canonical confluence/ mirror:


npm run sync:confluence -- --plan confluence/sync-dry-run-template/readonly-probe-plan.json

It requires the approved read-only Confluence environment outside Git. It has no live Confluence writes. Promotion is a separate, reviewable repository mutation that consumes a verified report and writes canonical mirror artifacts under confluence/; it must be run on a clean review branch:


npm run sync:confluence -- --skip-probe --promote

# Equivalent direct mutation command:

npm run promote:confluence-snapshot -- --report .reports/confluence-readonly-probe/report.json

Scheduled sync PRs

The scheduled/manual protected-main workflow checks out github.sha, refetches and pins protected main before probing and publication, then probes and strictly verifies exact plan membership and expected versions, builds an isolated candidate, and lease-protected pushes only bot/confluence-sync. It creates or updates one PR to main; a bot-branch divergence or no-change candidate stops publication. Main is checked before candidate publication and again immediately after it. An advance can still race those checks, so the workflow preserves rather than deletes the lease-protected candidate, skips PR publication when the post-push check observes the advance, and lets a later run replace a recognized stale bot candidate using its observed-SHA lease. Human merge review must verify the PR against current main. The sanitized PR body contains counts, source-run metadata, validation, classification, and Git-revert rollback guidance only. It never contains page bodies or secrets, and it does not auto-merge. Routine output is bounded to allowlisted mirror/review-index paths; the staged mapping output is publication/confluence-targets/mapping-index.json, and deletions, mapping changes, and anomalies are explicitly review-required for a human decision. Semantically identical source snapshots preserve canonical metadata and create no candidate commit. Existing bot candidates are replaced only with an observed-SHA --force-with-lease; initial creation uses an absent-ref lease. The dedicated CONFLUENCE_SYNC_PR_TOKEN is supplied to Git through a temporary restrictive GIT_ASKPASS helper, not a URL or process argument. PR discovery is repository-qualified, paginated, and rejects ambiguity.

Use npm run probe:confluence-readonly for the explicit live read-only probe, or npm run import:confluence-scoped-metadata for report-to-.reports/ metadata conversion. The importer refuses confluence/; neither probe nor importer is a mirror promotion. Never hand-edit generated mirror content, and do not modify the immutable legacy paths RWS-ARCH/90-confluence/ and RWS-ARCH/90-confluence-analysis/.

Freshness is offline: it compares checked-in snapshot age, approved-plan page membership, and expected versions against local committed state only. It does not query or establish recency against live upstream Confluence. Run warning mode locally or in PR CI with npm run warn:confluence-freshness; drift findings are reported but exit successfully. npm run enforce:confluence-freshness uses the same deterministic local report and exits nonzero for findings, ready for a future CI switch. Missing or malformed required JSON, paths, metadata, or sync error counts fail both modes; a missing or unreadable sync timestamp is a freshness finding, so warning mode reports it successfully while enforcement fails. Age uses the current clock, so its result naturally changes as time passes without a repository change. PR CI deliberately runs warning mode without Confluence secrets, and therefore cannot verify or prove live upstream state. Tests may pass --now <ISO-8601> for a reproducible age evaluation. Manifest-controlled report and metadata paths are contained beneath the approved sync-report and page roots; path escapes are operational failures. The report schema is confluence-freshness-v2; the legacy warningOnly field is retained for compatibility, while consumers should prefer mode, status, scope, and liveUpstreamChecked.

The representative fixture slice added for TASK-023 deliberately stays synthetic: it expands the INFRAARCH tree with a platform-services hub, an API connectivity SBB, and a risk-register appendix so reviewers can inspect nested navigation, macro-heavy storage, attachment metadata, comments, long tables, and content-heavy source details before any approved real Confluence content is mirrored.

Proposal workflow

Human-authored work starts under workbench/ or architecture/. Reviewable change packages live under proposals/ and should reference the mirrored source page version they are based on.

Publication candidates live as page-scoped proposal units under proposals/page-changes/<candidate>/candidate.json with a paired proposal body. Candidate reports live under publication/readiness/ and apply template contracts without mutating mirrored source.


npm run validate:candidate-pages

In the fixture milestone, required candidate checks are blocking for the report, while mirrored source drift remains report-only. Real candidates still need a separate review of content classification, preview exposure, and Confluence staging mechanics.

Negative fixtures are allowed only when generatedFrom.expectedValidation is fail and the paired readiness report contains a failing required check plus a failing prCheck conclusion. This keeps regression coverage for candidate gates without blocking local CI. Passing reports and negative reports use the same schema so later Forgejo check automation can consume one readiness shape.

Generated review indexes are produced by:


npm run validate:review-indexes

The generator writes .reports/generated/source-index.json, .reports/generated/candidate-index.json, .reports/generated/report-index.json, and .reports/readiness-summary.md. Portal routes read these generated indexes for source browsing and candidate-report tables instead of maintaining explicit imports for every fixture report.

Review cockpit workflow

The portal is still static and fixture-only, but Milestone 10 changes the review entry point from status tables to an architecture review cockpit. Start at /, triage the highest-priority item, and then branch to source context, findings, compliance, or PR review mode.

Before colleague-facing previews are enabled, perform a focused UX gate:

  1. Desktop around 1440px: triage, action metrics, route cards, and review tables
  2. fit without page-level horizontal scroll.

  3. Tablet around 768px: cockpit and review panels collapse in source-first order.
  4. Mobile around 390px: navigation wraps, disclosures remain tappable, and tables
  5. scroll inside their panels only.

  6. Keyboard: the skip link reaches main content and focus remains visible on
  7. route cards, details disclosures, and source/finding links.

  8. Content-heavy source page: escaped Confluence storage stays behind a
  9. disclosure control until sanitizer and macro policy are approved.

These gates are now repeatable evidence. The evidence:preview script exercises every configured route at desktop, tablet, and mobile sizes, but stores only two screenshots that provide distinct review value: desktop Confluence navigation and mobile architecture rendering. It rejects page-level horizontal overflow and writes the bundle to .reports/preview-evidence/. In CI it launches Chromium with --disable-dev-shm-usage to avoid constrained shared-memory capture failures; local launches retain Playwright's default arguments.


npm run setup:preview-evidence

npm run validate:preview-evidence

The evidence bundle copies the generated source, candidate, and report indexes plus .reports/readiness-summary.md beside manifest.json and the screenshots. This ties the portal build, readiness state, generated indexes, and visual QA to one local working tree or Forgejo commit without requiring runtime secrets. The Evidence gallery links each retained capture to a full-size review route under /evidence/<route>-<viewport>/, where reviewers can inspect the image at browser scale and cite the manifest path, commit, generated timestamp, viewport, and screenshot path from the same screen. Assertions, not duplicated screenshots, provide coverage for the remaining route and viewport combinations. CI requires Chromium installation and successful browser evidence capture. Local placeholder evidence is available only with explicit ALLOW_PREVIEW_EVIDENCE_FALLBACK=1 when the browser executable is unavailable; assertion failures never fall back. Diagram pair parity, SVG/Drawio safety, and browser decode are validated. Exact source-to-export freshness is explicitly unavailable; no report claims it. The diagram safety validator has a path-scoped legacy compatibility allowlist for five immutable Draw.io sources and five matching legacy exports whose historical serialization contains DTD/entity or embedded-image forms. The allowlist is reported in .reports/diagram-safety.json; it is not a general exemption for new diagrams. It contains exactly 15 exception records over 10 artifacts: five Draw.io external-image records and two SVG serialization records for each of five SVGs. exceptionRecords counts rule/path authorizations; exceptionArtifacts counts unique paths.

CI evidence reports are versioned and validated against .schemas/ci/. The structural validate:all command does not require generated reports. After portal generation, run the matching profile sequence:


npm run build:portal && npm run validate:built-routes && npm run setup:preview-evidence && npm run verify:confluence-browser

npm run write:ci-evidence-provenance -- --profile browser-verify

npm run validate:ci-evidence -- --profile browser-verify



npm run build:portal && npm run validate:built-routes && npm run setup:preview-evidence && npm run evidence:preview

npm run write:ci-evidence-provenance -- --profile preview

npm run validate:ci-evidence -- --profile preview

The ignored .reports/ci-evidence-provenance.json uses sha256-manifest-v1, records full event-derived commit provenance, and hashes the explicit, lexically sorted Phase 1 source and generated report list. Pull requests require same-repository full base/head SHAs; pushes use event before/after (with a null base and initial-push context for an all-zero before). Local and dispatch runs use HEAD plus merge-base HEAD origin/main or CI_EVIDENCE_BASE_SHA; when no base is available they explicitly record the local-working-tree context and a null base. It intentionally does not hash the complete portal dist tree.

Phase 2 CI routing

The CI workflow runs for every pull request and main push: it deliberately has no trigger path filters. A deterministic Node classifier uses the event SHA range when available; malformed, unavailable, or unknown event data selects the full pipeline. Documentation and review-agent-only changes run fast validation only; architecture and portal changes also run build and browser evidence; workflow, validator, schema, dependency, and unknown paths run all phases. The runner uses no dependency cache. Build Portal builds and validates Astro exactly once, then runs browser verification and preview evidence against that same apps/portal/dist workspace. The portal build is never uploaded as an artifact, so the runner discards it with the job workspace after all consumers finish. The separate Browser Verification and Preview Evidence jobs publish the phase results for CI consumers without rebuilding or transferring the portal. The combined job clears completed browser reports before validating the isolated preview evidence profile. The bounded review and preview evidence artifacts remain unchanged. The classifier publishes versioned provenance, status, SHA range, and a compact reason-code list. Each phase publishes an exact phase status only when it completes successfully: passed when selected or skipped_by_classifier when unselected. CI Gate records this selected-phase truth table with classifier provenance and fails closed for missing, mismatched, blocked, or failed required jobs. PR summaries use the trusted-main controller and the existing PREVIEW_COMMENT_TOKEN baseline only for same-repository pull requests.

Phase 3 review evidence

Browser CI produces a separate, bounded PR artifact named rws-arch-wb-review-evidence only after the browser reports validate. It contains exactly browser-evidence.json and provenance.json, not screenshots, routes, selectors, browser messages, page text, or paths. The browser report uses configured route and viewport identifiers and counts only. The provenance records repository ID 9/name, PR and run identity, main base branch, and marks the producer as pr-controlled-advisory; it is therefore useful evidence but not trusted-main proof.

The /review adapter is dormant by default. It requires both OPENCODE_REVIEW_EVIDENCE_ENABLED=1, a dedicated REVIEW_EVIDENCE_TOKEN, and an explicit FORGEJO_REVIEW_EVIDENCE_API_VERSION=v1 configuration value. It never reuses PREVIEW_COMMENT_TOKEN, does no network I/O while disabled, and does not receive the review workflow run ID. When the explicit API contract is enabled, it queries the exact open same-repository PR for its head SHA, then the CI workflow run, browser task artifact, and ZIP bundle. It rejects absent or duplicate runs and artifacts, unsafe redirects, symlinks, paths, duplicate entries, oversized content, schema failures, and provenance mismatches. The controller receives only a normalized count/status summary; it never gives raw artifact content to a model. Disabled or unavailable portal evidence makes the review baseline incomplete (DISCUSS), while a validated failed browser task deterministically yields NEEDS_CHANGES. Secret provisioning and activation remain out of scope for this phase.

Workbench UI/UX workflow

Milestone 15 treats the portal as an architecture workbench rather than a demo site. Navigation follows these cohesion rules:

  1. The global top navigation is the stable route switcher for status, source,
  2. findings, compliance, reviews, issues, mockups, and evidence, but it must stay compact enough on mobile that route content starts quickly.

  3. Breadcrumbs state the current route purpose before dense workbench surfaces.
  4. Source routes keep Confluence context visible through a left-side tree and a
  5. page-detail workspace; page detail routes preserve the same tree context.

  6. The issue workflow page is an operations contract: Forgejo issues hold the
  7. live queue, labels hold state, comments hold history, and issue-linked PRs hold implementation review.

  8. Mockups are comparison routes that use the same fixture data as production
  9. routes, not decorative screenshots or disconnected design artifacts.

Visual-density targets for the workbench are:

  1. Prefer compact headers, route labels, metrics, and panels over oversized hero
  2. surfaces on task-oriented routes.

  3. Keep source hierarchy, metadata, artifact paths, and review actions visible in
  4. one viewport on desktop where practical.

  5. Use restrained radii, tighter spacing, and clear contrast while preserving the
  6. existing fixture-only safety language.

  7. Keep tables and escaped storage panel-scrolled instead of allowing page-level
  8. horizontal overflow.

The preview evidence gate now also captures /confluence/, a representative /vault/ article, /mockups/, and a representative full-size evidence review page. It verifies that the source browser exposes a workspace and either real mirror controls or a real-sync empty state, that the issue workflow route exposes label-driven implementation plumbing, and that the mockup switcher exposes at least three design directions. The same gate performs focused keyboard paths across the Evidence gallery, breadcrumbs, source browser, issue workflow links, mockup cards, and mockup route-rail links, then confirms that the full-size route exposes the screenshot/text-evidence target and all viewport switcher links without page-level horizontal overflow.

The local comparison against the prior portal implementation found useful patterns to carry forward without coupling this repository back to that source: a shared shell with active route state, a Confluence-like tree plus selected content plus inspector layout, progressive disclosure for large hierarchies and generated data, and institutional RWS-blue/yellow accents. The workbench should intentionally diverge from heavier theme switching, tall mobile chrome, and broad exploration-first dashboards; its durable shape should stay operational, with source fidelity, evidence proof, task state, and review handoff visible early.

TASK-017 recorded the initial UX direction in docs/frontend-ux-direction.md. TASK-019 supersedes it with the durable baseline captured in architecture/decisions/0001-choose-workbench-visual-direction.md: source-first tree/workspace/inspector layout, operations-rail density, RWS-blue/yellow institutional accents, progressive disclosure, and selective decision-studio proof framing. Mockups remain available as decision evidence, but they should not stay a primary navigation destination after the durable direction is selected.

Confluence source experience workflow

Milestone 16 completed the full fixture-backed Confluence source experience foundation before live sync work starts. The source browser moved from large tree cards toward a dense source-index style menu with compact rows, active ancestry, short labels, path or hierarchy hints, artifact type, status/version metadata, and enough scan density for a large Confluence space. The existing architecture portal preview provided inspiration for density and information rhythm, but this workbench maintained its own implementation, validation, and safety boundaries.

Rendering Confluence pages is a separate gate from syncing Confluence pages. Before any real snapshot is imported or exposed, fixture storage XHTML should prove:

  1. Sanitized rendering for basic Confluence content: headings, paragraphs, lists,
  2. tables, links, code/pre blocks, panels, and basic formatting.

  3. Safe placeholders for unsupported macros, with macro names and approved
  4. parameters visible but no script execution or remote resource trust.

  5. Link rewriting from mirrored Confluence links to local source routes, plus clear
  6. unresolved-link and external-link states.

  7. Local overflow controls for wide tables, code blocks, long titles, and rendered
  8. fragments so the page itself does not scroll horizontally.

  9. Context panels for breadcrumbs, ancestors, children, labels, versions,
  10. attachments, comments, source paths, template/contract hints, findings, readiness signals, and activation blockers.

Milestone 16 is complete: preview evidence covers dense navigation, rendered page content, macro placeholders, attachments/comments, filters, analysis/readiness signals, keyboard paths, unsafe markup rejection, and desktop/tablet/mobile overflow behavior. Milestone 17 may now focus on scoped Confluence sync instead of redesigning browsing and rendering while credentials and real content are in play.

The implementation pass for TASK-033 through TASK-037 is complete for the synthetic fixture path. The Source route now exposes compact source-index rows, search plus artifact/label filters with URL state, sanitized fixture rendering, macro and attachment placeholders, local fixture page-link rewrites, context panels, candidate readiness, page-analysis coverage, linked findings, and explicit activation blockers. The preview evidence gate verifies the source filters, rendered storage, macro placeholders, rewritten fixture links, context panels, unsafe markup rejection, keyboard reachability, and page-level overflow across desktop, tablet, and mobile captures. TASK-038 is complete and documented the final done criteria that allowed Milestone 17 sync planning to start.

The storage renderer is code-gated to fixture mirrors and to reviewed real snapshot pages. A snapshot route may call set:html only when the generated index reports mode: snapshot, the payload policy is metadata-with-storage, and the page ID is in the committed reviewed real-rendering set. Pages outside that guard fail closed to the escaped storage fallback. npm run validate:safe-storage covers fixture regressions plus snapshot-mode adversarial storage, representative real mirror structures, local link rewrites, tables, panel/code macros, inert unsupported macro placeholders, attachment metadata placeholders, unsafe hrefs, blocked tags, event attributes, and the reviewed rendering guard. The renderer does not fetch attachment binaries, comment bodies, credentials, Confluence live views, or remote active content.

Confluence sync activation workflow

TASK-039 records the scoped sync activation plan in architecture/decisions/0008-plan-scoped-confluence-sync-activation.md. The first implementation may only build dry-run tooling and must stay within these bounds:

  1. Limit the first candidate snapshot to a small, classification-approved page set
  2. from one Confluence space.

  3. Resolve credentials through an approved profile or platform secret outside Git;
  4. never commit tokens, Basic Auth hashes, runtime values, or real storage content.

  5. Default every command and workflow to dry-run and no-live-write until a manual
  6. approval names the page set, credential scope, retention, and rollback path.

  7. Stop on version conflicts; automated overwrite of newer Confluence content is
  8. not approved.

  9. Keep attachment binaries and comment writes disabled until separate
  10. classification and rollback reviews approve them.

  11. Produce sync reports that record scope, expected and observed versions,
  12. conflicts, artifact counts, rate-limit behavior, generated artifacts, and rollback or removal instructions.

TASK-040 remains blocked for Confluence writes and staging until its remaining activation criteria are resolved. ADR 0010 authorizes authenticated preview evidence for committed content; public exposure and staged page writes remain outside that decision.

TASK-0101 through TASK-0103 now have the first review artifacts for the new roadmap model: publication/approvals/TASK-0101-approval-package.md, the fixture-only npm run sync:confluence-fixture-dry-run command, and publication/dry-runs/TASK-0103-dry-run.md. These artifacts prepare review and validation only. They do not approve live reads, repository import of real RWS content, generated-index exposure, preview screenshots, PR comments, or Confluence writes.

TASK-0101 now records the Datacenter architecture as the first candidate family, with page IDs, latest observed versions, URLs, attachment totals, and Wouter as the current reviewer. It also records decision-level answers: use the existing confluence OpenBao profile if it is least-privilege/read-only enough, create a separate weekly/manual sync workflow, allow same-repository PR feedback in the private Forgejo context, emit a private CI artifact first, mirror full page storage, allow approved private/authenticated review surfaces and full private PR summaries, rotate/revoke on demand, and keep routine superseded content in Git history. TASK-0107 must implement and verify CI credential delivery and no-live-write controls before TASK-0103 can perform a live read. The read-only sync fetches current Confluence versions at runtime instead of failing on TASK-0101 drift; TASK-0108 defines scoped metadata contracts, and TASK-0109 closes the index-only hierarchy, attachment-summary, and comment-summary gaps needed before storage import. TASK-0107 now also records the first proof shape: use the same ubuntu-latest runner convention as existing jobs, fetch only the three scoped page metadata records, emit report/metadata artifacts by default, target short retention, and prefer PR comments only after normal content review.

The first implementation proof adds .forgejo/workflows/confluence-sync.yml, .scripts/confluence-readonly-probe.mjs, .scripts/validate-confluence-readonly-probe.mjs, and confluence/sync-dry-run-template/readonly-probe-plan.json. The credential-bearing job runs only on schedule or manual dispatch for refs/heads/main, explicitly checks out the protected default branch, resolves credentials through the Forgejo repository Actions secret CONFLUENCE_TOKEN, kept as a CI platform-secret copy sourced from the approved OpenBao confluence profile, requires CONFLUENCE_SYNC_APPROVED=readonly-probe, marks the approved three-page credential boundary, fetches metadata plus body.storage for only the three TASK-0101 pages from the approved Confluence origin, and writes a private storage-bearing read-only report artifact with one-day retention. The workflow verifies the report before artifact upload by calling .scripts/verify-confluence-readonly-report.mjs: three scoped pages, approved origin, storage representation/hash/byte counts, zero write methods, no comment-body or attachment-payload fields, no credential/header printing, no forbidden credential markers in the report body, the approved boundary marker, and no tracked repository mutation before report writing. Pull-request events run a no-secrets guard artifact instead of the credentialed probe. The first protected-branch dispatch failed before producing a report artifact while using runner-local mit-secrets; follow-up switched CI to the approved Forgejo platform-secret delivery path and added an explicit token-delivery preflight. The updated protected-branch dispatch succeeded with the report verifier enabled in the trusted private Forgejo runner environment. Commit fc681ae then moved the verifier into .scripts/verify-confluence-readonly-report.mjs, and protected-branch Confluence workflow run 1195 passed with that committed verifier.

The blocker interview on 2026-06-30 approved the existing confluence OpenBao profile for the guarded three-page read-only probe, allowed protected-branch scheduled/manual CI runs, accepted a private Forgejo report artifact with one-day retention as operational output, approved same-repository PR comments after normal content review, and set TASK-0102 sequencing to use the first real metadata report before fixture storage/comment/attachment schema work. The follow-up access-proof interview on 2026-07-01 removed artifact-audience, fork/untrusted misuse, and named runner-trust proof blockers: the repository and runner environment are private, controlled by Wouter, and all configured Forgejo runners are trusted. Proactive token rotation is not required before TASK-0103. TASK-0108 records the scoped importer/schema proof for metadata-only page, manifest, tree, attachment-index, and comment-index contracts. TASK-0109 closes the remaining index-metadata fields. Scoped page storage may be imported only after CI no-live-write proof; comment bodies remain out of scope unless separately approved.

TASK-0102 now includes a report-to-index dry-run command, .scripts/import-confluence-scoped-metadata.mjs, for verified read-only report shapes. The importer rejects skipped or unverified reports, accepts only the approved three-page storage-bearing scope, refuses output under confluence/, and writes metadata-only manifest, tree, children, attachment-index, and comment-index artifacts only under .reports/ or OS temp paths. Promotion to confluence/ is a separate reviewed branch step.

Use the fixture dry-run command during local validation when changing the scoped sync design:


npm run sync:confluence-fixture-dry-run

npm run import:confluence-scoped-metadata -- --report .reports/confluence-readonly-probe/report.json --out-dir .reports/confluence-scoped-metadata

npm run validate:sync-dry-run-design

npm run validate:confluence-readonly-probe

npm run validate:scoped-metadata-importer

npm run validate:scoped-metadata-import-dry-run

npm run verify:confluence-readonly-report -- --report .reports/confluence-readonly-probe/report.json

The command writes no files by default. If --out is used, the output path must be under .reports/ or the OS temp directory, never under confluence/.

Broad Confluence mirror and mapping workflow

The broad mirror path generalizes the three-page proof without changing the authority model. A reviewed plan may name a larger page inventory, but it must still use read-only Confluence requests, approved field selection, report redaction, body.storage hashes, and no comment bodies or attachment payloads.

The scripted operator path is:


CONFLUENCE_BASE_URL=https://rws-confluence.prepend.net \

CONFLUENCE_CREDENTIAL_BOUNDARY=approved-broad-confluence-mirror-profile \

CONFLUENCE_SYNC_APPROVED=readonly-probe \

npm run sync:confluence

In practice, provide the Confluence token through the approved secret/profile environment; do not write token values into shell history, docs, reports, or Git.

That command runs the read-only probe, writes .reports/confluence-readonly-probe/report.json, verifies the report, and emits .reports/confluence-readonly-probe/pipeline-summary.json. It does not write confluence/. To promote a verified report into the Git mirror on a clean review branch, run:


npm run sync:confluence -- --skip-probe --promote

npm run build:portal

npm run verify:confluence-browser

Promotion reuses the verified report, writes the immutable mirror artifacts under confluence/, regenerates mappings and review indexes, then validates the promoted mirror. The pipeline refuses promotion when tracked changes are already present, so source mirror diffs stay reviewable and easy to revert.

Broad plans are allowed to be imperfect at first. The workflow is to import the approved corpus, generate mappings, validate stale or unresolved records, and fix them through follow-up imports or review rather than blocking the whole workbench on perfect first-pass modeling.

The checked-in RWS-ARCH/ tree is the repository-local architecture authoring and validation root. Its immutable Confluence mirrors remain under RWS-ARCH/90-confluence/ and RWS-ARCH/90-confluence-analysis/; mapping and publication changes remain separate follow-up work.

Analysis workflow

Analysis objects are authored outside the immutable mirror. Each page analysis must reference a specific Confluence page metadata file, storage fragment, and version. Findings should reference source artifacts, severity, confidence, status, impacted area, and a recommended action. Evidence entries carry provenance and usage constraints for the claims used by reports.


npm run validate:analysis

The current Datacenter report is fixture-only. Before analyzing real ABB/SBB/HLD content, review source identification rules, evidence retention, preview exposure, and whether findings may contain sensitive RWS architecture details. TASK-0401 adds a draft fixture-first comparison model in analysis/findings/TASK-0401-findings-comparison-model.md; it remains blocked from final acceptance until full sync and architect validation.

Preview workflow

Pull requests may receive a preview comment that points to https://pr-<number>.rws-arch-wb.moeken.eu. The comment workflow remains separately token-gated. Authenticated preview route rendering follows ADR 0010 and does not itself activate infrastructure changes.

Candidate readiness reports now pre-shape the future PR check payload: check name, conclusion, summary, and file-level annotations. The current CI summary publishes those reports as artifacts only; no live PR status API writes are enabled yet.

Preview publication evidence is uploaded by the portal-build job as the rws-arch-wb-preview-evidence artifact. It contains the same manifest, screenshots, readiness summary, and generated indexes produced locally by npm run evidence:preview. Forgejo status contexts, live PR comment enrichment, and Confluence staging remain gated; authenticated rendering of committed content is governed by ADR 0010.

Milestone 12 chooses the safe fixture publication path: the uploaded evidence artifact is the durable readiness bundle, and the optional preview comment is a non-secret pointer to that bundle. If PREVIEW_COMMENT_TOKEN is absent, the comment workflow exits without writing. If the token is configured later, the comment must still say that authenticated preview access, Forgejo status contexts, real RWS content exposure, and Confluence staging are not enabled.

TASK-008 records the current live-write boundary in architecture/decisions/0002-live-preview-write-boundaries.md: keep PREVIEW_COMMENT_TOKEN unset by default, require verified repository-only minimum comment permissions and fork or untrusted-PR secret behavior before activation, keep the token-bearing workflow free of PR checkout and PR-code execution, and defer Forgejo status contexts until an automated consumer needs machine-readable status beyond CI artifacts and the gated comment.

TASK-030 records the current status-context decision in architecture/decisions/0007-defer-forgejo-status-contexts-until-a-consumer-exists.md: do not add custom Forgejo status contexts for the fixture review path. Existing CI job results, the uploaded rws-arch-wb-preview-evidence artifact, and the gated preview comment are the chosen publication mechanism until a named branch-protection, release-gate, deployment, or dashboard consumer needs a custom machine-readable context. Any later status writer must first document its consumer, token permission, fork behavior, rollback path, and data-exposure boundary.

TASK-009 records the current authenticated access and staging gate review in architecture/decisions/0004-keep-authenticated-preview-and-staging-gates-blocked.md: the OpenShift values remain non-live examples and do not approve authenticated previews, real RWS content exposure, or Confluence staging. TASK-028 is complete in architecture/decisions/0005-preview-deployment-ownership-and-cleanup-contract.md: the contract requires secret-free proof for DNS/TLS ownership, authenticated access, secret delivery, ArgoCD ownership, quota boundaries, cleanup evidence, orphan reconciliation, and rollback or removal before live preview resources are implemented. TASK-029 is complete in architecture/decisions/0006-confluence-staging-rollback-and-data-handling.md: the review requires content classification, hosting, artifact retention, generated metadata exposure, scoped staging credentials, dry-run defaults, version-conflict refusal, partial-write recovery, attachment and comment policy, audit trail, and rollback proof before real-content exposure or staged page writes are activated.

Before live preview writes or colleague-facing previews are activated, review:

  1. PREVIEW_COMMENT_TOKEN scope, repository permissions, event restrictions, and
  2. fork or untrusted-PR behavior.

  3. Whether screenshots, generated indexes, readiness summaries, branch metadata,
  4. preview URLs, and PR comments may expose real RWS architecture details.

  5. DNS, TLS, ingress, Basic Auth, ArgoCD ownership, preview resource retention,
  6. and cleanup proof for opened, synchronized, closed, and merged PRs.

  7. Whether a named consumer now needs custom Forgejo status contexts beyond the
  8. CI job status, artifact, and gated comment bundle.

  9. Confluence staging credentials, draft permissions, version-conflict handling,
  10. and rollback behavior before any staged page write is implemented.

Cleanup evidence is intentionally placeholder-only for fixture previews. Live preview cleanup evidence must prove which resources were created, who could access them, when they were removed, and which commit or PR event triggered the cleanup.

Issue planning workflow

Forgejo issues now replace the repository-local roadmap system for operational planning. Use docs/roadmap.md only as a pointer to the current issue-first model; do not maintain a second backlog in the portal.

The staged issue-agent controller is documented in docs/issue-agent-workflow.md. Use that document as the operational reference for label scopes, autonomy profiles, delivery modes, slash commands, deterministic gates, and agent runtime behavior.

Use these rules for ordinary work updates:

  1. Create or update a Forgejo issue for every work item that needs planning,
  2. implementation, review, or follow-up discussion.

  3. Apply scoped labels from workbench/issue-workflow/labels.json for type,
  4. status, priority, automation intent, gates, and area ownership.

  5. Keep acceptance criteria and scope tuning in the issue body/comments.
  6. Link implementation branches, pull requests, CI runs, artifacts, and evidence
  7. paths back to the issue.

  8. Use agent/implement only when the issue is ready for the issue-agent
  9. workflow to prepare an OpenCode run. The workflow installs the shared runtime from MoekenIT/agent-skills before invoking OpenCode and records the exact agent-skills commit in the run artifact/comment.

  10. Add gate/* labels and keep work blocked when Confluence access, real RWS
  11. content exposure, preview deployment, platform ownership, or human approval is required.

Use this sequence for ordinary issue workflow changes:

  1. Update workbench/issue-workflow/labels.json when the taxonomy changes.
  2. Update workbench/issue-workflow/milestones.json when the issue milestone
  3. containers change.

  4. Update .forgejo/issue_template/ templates when issue intake changes.
  5. Update .forgejo/workflows/issue-labels.yml or
  6. .forgejo/workflows/issue-agent.yml when automation behavior changes.

  7. Run npm run ci:local before committing so generated indexes, docs,
  8. workflows, portal build, build-impact checks, issue workflow validation, and preview evidence stay aligned.