Skip to content

ci(workflow): make the required gate execute and verify what it ships (Wave 0) - #80

Merged
cemililik merged 6 commits into
mainfrom
development
Jul 29, 2026
Merged

ci(workflow): make the required gate execute and verify what it ships (Wave 0)#80
cemililik merged 6 commits into
mainfrom
development

Conversation

@cemililik

@cemililik cemililik commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Wave 0 of the Phase 2.5.5/2.6 execution order — the CI-truth batch.

One root cause across eight items: a guard that claimed a stronger guarantee than it enforced. Landed as one change because five of them edit the same file family, and splitting would leave the gate self-inconsistent in between.

# Gap Finding
1 The required ci job never ran the binary it built #294
2 apps/cli/drizzle/** was not a declared turbo build output #315
3 pnpm ci and ci.yml had diverged in both directions #312
4 Coverage floor documented as enforced, configured as advisory #296, #152
5 Two advisory jobs did not say so in their name: #320
6 THIRD_PARTY_EXTERNAL stale vs package.json (string-width) G27, #248
7 Bundle-closure read one chunk without asserting there is one #314
8 sync:models:check implemented, documented, called by nothing #317

The two worth reading closely

#315 — the stale-artifact class. tsup's onSuccess copies the migrations to apps/cli/drizzle/, outside dist/, and turbo only restores declared outputs. A cache-hit replay could therefore leave dist/index.js fresh beside a missing drizzle/ and crash on first DB touch, with nothing red anywhere. Verified empirically, not reasoned about: deleted the directory, replayed from cache — 14 files restored after the fix. Item #1's run --json smoke is what would now catch a regression here, which is why the two belong in one change.

#296/#152 — the coverage contradiction, resolved by ruling not by wording. llm and mcp become a REQUIRED check; core stays measured-and-printed but non-blocking. Its branch margin is +0.83 (90.83, measured 2026-07-29) and Phase 2.5.5's Waves 1–3 edit core heavily — gating merges on a sub-1-point margin would red-CI real work for no defect. This is a scoped, dated ruling with a stated promotion trigger (Wave 3's test-coverage items), not an open-ended exemption. A local pnpm coverage still enforces all three.

Behaviourally verified: with core's floor temporarily raised to 99, pnpm coverage:enforced passes and pnpm coverage fails — exactly the intended split.

testing.md is corrected here rather than later, because the standard asserted an enforcement the pipeline did not perform; stating the split only in ci.yml would leave that contradiction in the standard.

Maintainer action required after merge

Add engine coverage floor (llm, mcp) to the required status checks in branch protection. The workflow change alone does not make it required — that is a repo setting, and until it is set this item is only half-landed.

Conformance

Every gate run locally, exactly as CI will:

  • lint · typecheck · test · format:check · lint:tools · fence-check · engine-deps · bundle-closure · db:sync-check · coverage:enforcedall exit 0
  • The new binary smoke (--version, --help, fixture run --json) — exit 0
  • No @relavium/llm seam widening, no platform import into packages/core, no --json shape change
  • No new dependency, no ADR minted

G26 (release-ref ancestry) was in Wave 0's list and already landed in #77, so it is not repeated here.

🤖 Generated with Claude Code

Summary by Sourcery

Tighten CI gates so the required workflow actually validates the artifacts it ships while clarifying and partially promoting engine coverage enforcement.

New Features:

  • Add a smoke test in the required CI job that runs the compiled CLI binary with basic commands and a JSON fixture.
  • Introduce a coverage:enforced script and workflow wiring that makes llm and mcp coverage floors required while keeping core measured but non-blocking.
  • Add an informational snapshot-freshness check for the models catalog that reports drift without failing the workflow.

Bug Fixes:

  • Ensure CLI bundle-closure guard asserts that the build produces exactly one JS output chunk, preventing silent narrowing of the closure check when chunks split.
  • Declare apps/cli/drizzle as a turbo build output so migrations are restored on cache replays instead of becoming stale artifacts.
  • Align the required CI workflow with the pnpm ci script by linting tooling code and adding a DB migration sync check so local and CI gates match.
  • Update engine coverage enforcement so CI no longer claims to enforce a core coverage floor it does not actually gate on.

Enhancements:

  • Label advisory CI jobs explicitly in their names and mark coverage as a required status check for llm and mcp in branch protection guidance.
  • Document the split between local coverage expectations and enforced CI coverage subset in both vitest config and testing standards.
  • Extend package.json scripts with db:sync-check and wire it into CI to ensure committed DB migrations stay in sync with schema changes.

CI:

  • Refine ci.yml to add tooling linting, binary smoke tests, coverage:enforced usage, advisory naming for non-blocking jobs, and an informational models snapshot check.

Documentation:

  • Update testing standards to describe which packages’ coverage floors block merges versus remain informational, keeping the written standard aligned with CI behaviour.

Summary by CodeRabbit

  • CI & Quality
    • Added tools linting, a database migration consistency check, and a compiled CLI smoke test.
    • Improved bundle closure validation by detecting unexpected multiple JavaScript chunks.
    • Updated coverage enforcement so merge-blocking thresholds apply only to LLM and MCP; core is conditionally measured without blocking.
    • Added non-blocking model catalog snapshot freshness reporting.
  • Documentation
    • Refined testing/coverage documentation and clarified coverage gate behavior and local commands.
  • Build & Maintenance
    • Updated CLI build packaging to avoid bundling an additional dependency.

Wave 0 of the Phase 2.5.5/2.6 execution order — the CI-truth batch. Every item
below is one root cause: a guard that claimed a stronger guarantee than it
enforced. Landed as one change because five of them edit the same file family
and splitting them would leave the gate self-inconsistent in between.

* The required `ci` job never ran the binary it built (#294). Only the advisory
  Windows leg and the tag-gated release smoke ever executed
  `apps/cli/dist/index.js`, so a bundle that compiled but could not boot merged
  green. Adds a `--version` / `--help` / fixture `run --json` smoke.

* `apps/cli/drizzle/**` was not a declared turbo build output (#315), although
  `tsup`'s `onSuccess` copies the migrations there, outside `dist/`. A cache-hit
  replay could therefore leave `dist/index.js` fresh beside a stale or missing
  `drizzle/`, crashing on first DB touch with nothing red anywhere. Verified by
  deleting the directory and replaying from cache: 14 files restored after the
  fix, none before. Declared in a new `apps/cli/turbo.json` extending the root.

* `pnpm ci` and `ci.yml` had diverged in both directions (#312): the root script
  ran `lint:tools`, which CI never did; CI ran a DB-migration-sync check the root
  script never did. Adds the missing step to CI and a `db:sync-check` script to
  the root, mirroring CI's `git status --porcelain` (which, unlike `git diff`,
  also catches an untracked new migration).

* The >=90% engine coverage floor was documented as enforced and configured as
  advisory (#296, #152). Resolved by ruling rather than by wording: `llm` and
  `mcp` become a REQUIRED check; `core` stays measured-and-printed but
  non-blocking, because its branch margin is +0.83 (90.83, measured 2026-07-29)
  and Waves 1-3 edit `core` heavily. `RELAVIUM_COVERAGE_ENFORCED_ONLY=1` selects
  the CI subset; a local `pnpm coverage` still enforces all three, so the floor
  never silently relaxes for a developer. Behaviourally verified: with `core`'s
  floor raised to 99, `coverage:enforced` passes and `coverage` fails.

* `floor-check` and `peer-dep-gate` were advisory without saying so (#320) — the
  `name:` is what the PR checks list shows, so both now carry `(advisory)`.

* `THIRD_PARTY_EXTERNAL` was stale versus `package.json` (G27, #248):
  `string-width` shipped with ADR-0069 and was never added. Harmless today only
  because tsup auto-externalizes anything already in `dependencies`.

* The bundle-closure guard read one output chunk without asserting there is one
  (#314). Correct today, silently narrowing the moment a dynamic `import()`
  splits a chunk — which 2.5.5.E's `driveHome` deferral will do deliberately.

* `sync:models:check` was implemented, documented as the CI-facing staleness
  mode, and called by nothing (#317). Wired into the weekly job as
  `continue-on-error` so it reports drift without paging on ordinary churn.

`testing.md` is corrected in the same change rather than later: the standard
previously asserted an enforcement the pipeline did not perform, and stating the
split only in `ci.yml` would have left that contradiction in the standard.

Refs Phase 2.5.5 sub-stream H. G26 (release-ref ancestry) already landed in #77.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Reviewer's Guide

Aligns the required CI gate with what pnpm ci and the documented standards actually enforce: the required workflow now lints tools, smokes the compiled CLI binary, enforces coverage floors only for llm/mcp while measuring core, hardens the bundle-closure and DB migration guards, and wires the previously-unused models catalog snapshot check — plus keeps third‑party externals and turbo outputs consistent.

Sequence diagram for the required CI job building and smoking the CLI binary

sequenceDiagram
    participant GitHubActions_ci as GitHubActions_ci
    participant Turbo as turbo_run
    participant DB as db_sync_check
    participant ToolsLint as lint_tools
    participant BundleClosure as lint_bundle_closure
    participant CLI as node_apps_cli_dist_index

    GitHubActions_ci->>Turbo: pnpm ci
    activate Turbo
    Turbo->>Turbo: turbo run lint typecheck test
    Turbo->>DB: pnpm db:sync-check
    DB-->>Turbo: exit 0 or fail on drift
    Turbo->>ToolsLint: pnpm lint:tools
    ToolsLint-->>Turbo: eslint tools
    Turbo->>Turbo: turbo run build format:check
    Turbo->>BundleClosure: pnpm lint:bundle-closure
    BundleClosure-->>Turbo: node tools/bundle-closure/check.mjs
    deactivate Turbo

    GitHubActions_ci->>CLI: node apps/cli/dist/index.js --version
    CLI-->>GitHubActions_ci: print version
    GitHubActions_ci->>CLI: node apps/cli/dist/index.js --help
    CLI-->>GitHubActions_ci: print help
    GitHubActions_ci->>CLI: node apps/cli/dist/index.js run ... --json
    CLI-->>GitHubActions_ci: run fixture with migrations resolved
Loading

Flow diagram for coverage vs coverage:enforced split

flowchart LR
    A[pnpm coverage] --> B[Vitest with coverage]
    A --> C[thresholds for llm, mcp, core]

    D[pnpm coverage:enforced] --> E[RELAVIUM_COVERAGE_ENFORCED_ONLY=1]
    E --> F[Vitest with coverage]
    F --> G[thresholds for llm, mcp]

    C --> H[CI and local: all three packages enforce >=90%]
    G --> I[CI: llm and mcp enforce >=90%]
    I --> J[core measured and printed only]

    B --> H
Loading

Flow diagram for bundle-closure single-chunk assertion

flowchart LR
    A[Run lint:bundle-closure] --> B[node tools/bundle-closure/check.mjs]
    B --> C[read metafile outputs]
    C --> D[collect .js outputs]
    D --> E{jsOutputs.length === 1?}
    E -- No --> F[exit 1 with error about split bundle]
    E -- Yes --> G[use outputKey to inspect imports]
    G --> H[verify bundle closure invariants]
Loading

File-Level Changes

Change Details Files
Required CI gate now executes the built CLI binary and keeps its DB migrations in sync with turbo caching.
  • Add a smoke test step in the ci job to run the compiled CLI (--version, --help, fixture run --json).
  • Declare apps/cli/drizzle/** as a turbo build output for the CLI bundle so migrations are restored from cache.
  • Introduce db:sync-check script and run it as part of pnpm ci to assert committed DB migrations match generated drizzle output.
.github/workflows/ci.yml
apps/cli/turbo.json
package.json
CI job semantics and coverage enforcement are clarified and aligned between pnpm ci, workflows, Vitest config, and documentation.
  • Mark advisory jobs explicitly in their name: and document that ci and coverage are the required checks.
  • Split coverage into coverage (local, all three engine packages enforced) and coverage:enforced (CI subset: llm/mcp only), and wire the workflow to the enforced subset.
  • Add RELAVIUM_COVERAGE_ENFORCED_ONLY handling in Vitest config to drop core from thresholds under CI while keeping it covered locally.
  • Update testing standard docs to state that only llm/mcp floors block merges and that core is measured but non-blocking, matching the workflow.
.github/workflows/ci.yml
vitest.config.ts
docs/standards/testing.md
package.json
Tooling and guard scripts are now fully linted and hardened in CI, including the bundle-closure check.
  • Add a lint:tools step to the ci workflow so required CI runs tooling lint, matching pnpm ci.
  • Strengthen bundle-closure guard to assert the CLI bundle has exactly one .js output and fail if the bundle is split.
  • Keep lint:tools script definition aligned and ensure tools TypeScript project is typechecked via typecheck:tools in pnpm ci.
.github/workflows/ci.yml
tools/bundle-closure/check.mjs
package.json
Models catalog workflow now uses the existing snapshot-freshness check in informational mode.
  • Add a sync:models:check step to the models catalog workflow that runs after the guard and is marked continue-on-error so it reports staleness without blocking.
  • Leverage the already-implemented sync:models:check script instead of leaving it unused.
.github/workflows/models-catalog.yml
package.json
Third-party externals configuration is kept consistent with package dependencies.
  • Add string-width to the CLI bundle’s THIRD_PARTY_EXTERNAL list to match its presence in package.json and avoid stale external declarations.
apps/cli/tsup.config.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

CI coverage enforcement is scoped to llm and mcp, while core remains measured. Required checks now validate tooling, migrations, and the compiled CLI. CLI build metadata and bundle checks are strengthened, weekly model freshness reporting is added, and roadmap status and governance text is updated.

Changes

CI and Build Validation

Layer / File(s) Summary
Scoped coverage and CI contracts
vitest.config.ts, package.json, .github/workflows/ci.yml, docs/standards/testing.md, docs/roadmap/phases/phase-2.5.5-hardening-and-remediation.md
Coverage thresholds and CI commands enforce the 90% floor for llm and mcp, while core is measured without merge-blocking enforcement; related CI and testing requirements are updated.
CLI build and bundle integrity
apps/cli/turbo.json, apps/cli/tsup.config.ts, tools/bundle-closure/check.mjs, tools/cli-smoke/check.mjs, package.json
CLI build outputs are configured, string-width is externalized, bundle closure validation rejects multiple JavaScript outputs, migration synchronization is checked, and the compiled CLI is smoke-tested.
Required validation gates
.github/workflows/ci.yml, .github/workflows/models-catalog.yml
Required CI lints tooling scripts, executes compiled CLI smoke commands, and reports model snapshot freshness without making that report blocking.
Catalog and roadmap state updates
docs/roadmap/current.md, docs/roadmap/deferred-tasks.md, docs/roadmap/phases/phase-2.6-conversational-authoring.md
Roadmap documents update phase status, authority, deferred work, acceptance criteria, session-resume behavior, validation rules, and ADR references.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the CI workflow and shipping-verification focus of the main changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch development

Comment @coderabbitai help to get the list of available commands.

@HodeTech HodeTech deleted a comment from gemini-code-assist Bot Jul 29, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="package.json" line_range="20" />
<code_context>
     "test": "turbo run test",
     "coverage": "vitest run --coverage",
-    "ci": "turbo run lint typecheck test && pnpm typecheck:tools && pnpm lint:tools && turbo run build format:check && pnpm lint:fence-check && pnpm lint:engine-deps && pnpm lint:bundle-closure",
+    "coverage:enforced": "RELAVIUM_COVERAGE_ENFORCED_ONLY=1 vitest run --coverage",
+    "ci": "turbo run lint typecheck test && pnpm db:sync-check && pnpm typecheck:tools && pnpm lint:tools && turbo run build format:check && pnpm lint:fence-check && pnpm lint:engine-deps && pnpm lint:bundle-closure",
     "lint:fence-check": "node tools/lint-fixtures/assert-fence.mjs",
</code_context>
<issue_to_address>
**issue (bug_risk):** The `coverage:enforced` script uses POSIX env-var syntax, which will break on Windows shells.

On Windows shells (cmd.exe / PowerShell), this script will fail because the inline env-var assignment syntax isn’t supported. Since this command is used in CI and likely by Windows developers, consider a cross‑platform solution such as `cross-env RELAVIUM_COVERAGE_ENFORCED_ONLY=1 vitest run --coverage` or a small Node wrapper that sets the env var before running Vitest.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread package.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

6-15: 🎯 Functional Correctness | 🔵 Trivial

Synchronize the coverage job’s name, comments, and branch-protection setting.

The job is now presented as engine coverage floor (llm, mcp), while the adjacent block still says it is advisory and not required. YAML cannot change branch protection; verify that this exact status check is added as required after merge, and update the stale comment so the policy is unambiguous.

Also applies to: 214-214

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 6 - 15, Update the coverage policy
comments near the coverage job to identify its exact name, “engine coverage
floor (llm, mcp),” as a required status check rather than advisory, and remove
any stale statement that coverage is non-required. Keep the documented llm/mcp
enforcement scope and explicitly note that the matching branch-protection
requirement must be configured in GitHub repository settings after merging.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/models-catalog.yml:
- Around line 66-73: Reorder the workflow steps so “Snapshot freshness vs
upstream (informational)” runs before the mutating pnpm sync:models step. Keep
continue-on-error enabled, and preserve the existing guard behavior while
ensuring the check compares upstream against the committed snapshot before it is
rewritten.

In `@package.json`:
- Line 21: Update the root ci script to run the same compiled CLI artifact smoke
currently enforced by .github/workflows/ci.yml, extracting that smoke into a
shared script and invoking the shared script from both the package.json ci
command and the workflow path. Preserve the existing CI checks while ensuring
pnpm ci executes apps/cli/dist/index.js and catches its boot/drizzle failure.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 6-15: Update the coverage policy comments near the coverage job to
identify its exact name, “engine coverage floor (llm, mcp),” as a required
status check rather than advisory, and remove any stale statement that coverage
is non-required. Keep the documented llm/mcp enforcement scope and explicitly
note that the matching branch-protection requirement must be configured in
GitHub repository settings after merging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 209bae8b-eb6c-4b1e-82bf-993f82e8920a

📥 Commits

Reviewing files that changed from the base of the PR and between 311d2fe and 5449adc.

📒 Files selected for processing (8)
  • .github/workflows/ci.yml
  • .github/workflows/models-catalog.yml
  • apps/cli/tsup.config.ts
  • apps/cli/turbo.json
  • docs/standards/testing.md
  • package.json
  • tools/bundle-closure/check.mjs
  • vitest.config.ts

Comment thread .github/workflows/models-catalog.yml Outdated
Comment thread package.json Outdated
"coverage": "vitest run --coverage",
"ci": "turbo run lint typecheck test && pnpm typecheck:tools && pnpm lint:tools && turbo run build format:check && pnpm lint:fence-check && pnpm lint:engine-deps && pnpm lint:bundle-closure",
"coverage:enforced": "RELAVIUM_COVERAGE_ENFORCED_ONLY=1 vitest run --coverage",
"ci": "turbo run lint typecheck test && pnpm db:sync-check && pnpm typecheck:tools && pnpm lint:tools && turbo run build format:check && pnpm lint:fence-check && pnpm lint:engine-deps && pnpm lint:bundle-closure",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep pnpm ci aligned with the required artifact smoke.

The root command still never executes apps/cli/dist/index.js; a green local pnpm ci can therefore miss the compiled CLI boot/drizzle failure that .github/workflows/ci.yml now catches. Extract the smoke into a shared script and invoke it from both paths.

Suggested alignment
+    "smoke:cli": "node apps/cli/dist/index.js --version && node apps/cli/dist/index.js --help >/dev/null && node apps/cli/dist/index.js run apps/cli/src/harness/fixtures/sequential.relavium.yaml --input n=21 --json >/dev/null",
-    "ci": "... && pnpm lint:bundle-closure"
+    "ci": "... && pnpm lint:bundle-closure && pnpm smoke:cli"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` at line 21, Update the root ci script to run the same compiled
CLI artifact smoke currently enforced by .github/workflows/ci.yml, extracting
that smoke into a shared script and invoking the shared script from both the
package.json ci command and the workflow path. Preserve the existing CI checks
while ensuring pnpm ci executes apps/cli/dist/index.js and catches its
boot/drizzle failure.

cemililik and others added 2 commits July 29, 2026 18:54
…i` is unreachable

Two defects in the Wave 0 change, both found by CI doing exactly what this PR
added it to do.

`vitest.config.ts` read `process.env.RELAVIUM_COVERAGE_ENFORCED_ONLY` with dot
notation, which `noPropertyAccessFromIndexSignature` (tsconfig.base.json) rejects
— TS4111. It escaped local verification because `pnpm typecheck:tools` is a plain
`tsc -p tsconfig.tools.json`, NOT part of `turbo run typecheck`, and I ran the
turbo tasks individually rather than the root script this very PR exists to
align. Running that script would have caught it.

Attempting to run it then surfaced the second defect: `pnpm ci` does not invoke
the root `ci` script at all. pnpm 9 reserves `ci` as a builtin and answers
`ERR_PNPM_CI_NOT_IMPLEMENTED`, so the script is reachable only as `pnpm run ci`.
Finding #312 is therefore understated: the local mirror had not merely diverged
from `ci.yml`, it was unreachable by the name every contributor types, which is
why the divergence could persist unnoticed. Corrected in the `ci.yml` comment and
in current.md's Wave 0 entry; renaming the script is left as a maintainer call.

Verified with the full `pnpm run ci` — green end to end, including the
`typecheck:tools` step that failed in CI.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…26-07-29 review

A cross-document review raised 37 findings plus 5 proposal sections. Each was
verified against the live files rather than taken on faith; 14 were dropped as
cross-lane duplicates or declined on proportionality, and the review's own
10-step remediation order was rejected as a sequence — taken literally it puts
nine documentation edits ahead of Wave 1's three CRITICALs. current.md's waves
remain the execution authority.

Notably, none of the findings was closed by the 2026-07-26 propagation pass: the
review targets contract boundaries that pass never touched.

THE FOUR BLOCKERS, all verified before acting:

* 2.6.M instructed wiring the egress credential resolver into "the chat-session
  and workflow-run tool-environment factories" while the same document (Explicitly
  out of scope) and `build-engine.ts:87-89` both call the workflow-run egress/os
  arms permanently unwired and ADR-gated. An implementer following the plan
  literally would have breached a recorded security boundary. Scoped to the chat
  surfaces; the "every surface" acceptance clause now says "every surface that
  wires its capability arm".

* 2.6.O routed a model-generated `.agent.yaml` through `validateAuthoredWorkflow`,
  which 2.6.A scopes as workflow-shaped — leaving the plan's highest-risk path
  (untrusted context → generated agent → tool grants → execution) with no
  correctly specified gate. Adds the agent-shaped `validateAuthoredAgent` with the
  parent-grant clamp enforced INSIDE the validator, not only at spawn, since the
  artifact is persisted. 2.6.O acceptance gains a reject-path criterion.

* Visible session resume had no owner: deferred-tasks assigned it to "2.6.C's
  natural sibling or 2.6.G, whichever reaches it first", and 2.6.C shipped
  2026-07-13 without it. Assigned to 2.6.G, with the repaint written into the
  task, the acceptance, the pull-in table and exit criterion 2.

* Dynamic `invoke_workflow` was deferred by decision D57 and simultaneously
  carried in 2.6.P as an open "analysis gate". Recorded as deferred in the phase
  file and given its own deferred-tasks entry with the ADR + security review it
  needs to reopen.

TRUTH AND AUTHORITY:

* An authority notice now sits at the top of all three planning documents:
  current.md is canonical for progress and order, the phase files for scope and
  acceptance, and current.md may not redefine a security boundary or an
  acceptance criterion. The review found this model sound but undocumented.
* Status banners under-reported: 2.5.5 still said "Planned, not started" with
  Wave 0 in flight; 2.6 omitted 2.6.C and 2.6.Q P1-P5.
* The ADR table listed six Accepted ADRs (0067-0072) as "(new) — drafted when the
  workstream starts", with no link definitions. All six now resolve.
* current.md described PR #76 as open, the snapshot regen as pending, and D3 as
  "blocked on D3b" — a row that never existed. That dangling reference was mine,
  introduced 2026-07-26.
* Exit criterion 8 made the ABSENCE of an ADR a pass condition, which pressures
  against writing a genuine one. Reframed as the standing threshold: minting one
  is not a phase failure, skipping a genuine one is.
* Exit criterion 4 named `pnpm turbo run lint typecheck test` as the gate; the
  real contract is `pnpm run ci` plus both required ci.yml checks.
* Phase 2.5.5 claimed no new product surface while changing five public CLI
  contracts; they are now enumerated with the EXIT:4 reading that sanctions them.
* deferred-tasks.md mixed three lifecycle states with declined items rendered as
  open checkboxes. Legend added, declined items converted to plain bullets.
* The remaining five-language promise and the M2.6-3 milestone claim corrected.

Docs-only. Two stale source comments naming the retired `MODEL_PRICING` table are
folded into 2.5.5.F rather than fixed here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/roadmap/phases/phase-2.5.5-hardening-and-remediation.md`:
- Line 14: Remove the standalone blank blockquote line in the authority banner
so the entire banner remains one continuous blockquote and satisfies
markdownlint MD028.
- Around line 137-139: Update the required-check statement in the phase 2.5.5
roadmap to match the current branch-protection state: either state that coverage
promotion remains pending until the “engine coverage floor (llm, mcp)” check is
required, or update the documentation only after branch protection has added it.
Keep the documented CI command and existing check names accurate.

In `@docs/roadmap/phases/phase-2.6-conversational-authoring.md`:
- Around line 913-915: Update the roadmap entry for dynamic invoke_workflow to
state that it is tracked alongside 2.6.P but deferred past Phase 2.6, rather
than moved into 2.6.P. Preserve the references to workflow composition,
subworkflow, nested-run events, and D57 while making clear it is not a 2.6.P
implementation deliverable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 07f75626-24b7-4058-82f8-78ed373ed4f3

📥 Commits

Reviewing files that changed from the base of the PR and between 2f855fc and 53df0e7.

📒 Files selected for processing (4)
  • docs/roadmap/current.md
  • docs/roadmap/deferred-tasks.md
  • docs/roadmap/phases/phase-2.5.5-hardening-and-remediation.md
  • docs/roadmap/phases/phase-2.6-conversational-authoring.md

Comment thread docs/roadmap/phases/phase-2.5.5-hardening-and-remediation.md Outdated
Comment on lines +137 to +139
- `pnpm run ci` stays green throughout — it is `pnpm run ci`, never `pnpm ci` (pnpm reserves `ci` as a
builtin) — and so do both required `ci.yml` checks, the `ci` job including its compiled-binary smoke and
the `coverage` job (`pnpm coverage:enforced`); no item in this phase widens

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Align the documented required-check state with branch protection.

This says both CI checks are already required, while current.md still treats coverage promotion as a Wave 0 decision and the PR objective says branch protection must add engine coverage floor (llm, mcp) after merge. Clarify that these checks must pass, or update the status once branch protection is actually changed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/roadmap/phases/phase-2.5.5-hardening-and-remediation.md` around lines
137 - 139, Update the required-check statement in the phase 2.5.5 roadmap to
match the current branch-protection state: either state that coverage promotion
remains pending until the “engine coverage floor (llm, mcp)” check is required,
or update the documentation only after branch protection has added it. Keep the
documented CI command and existing check names accurate.

Comment thread docs/roadmap/phases/phase-2.6-conversational-authoring.md Outdated
cemililik and others added 2 commits July 29, 2026 20:13
…order the sync guards

Six review findings on PR #80. Two are defects this PR introduced.

* `coverage:enforced` used POSIX inline env-var syntax, which cmd.exe and
  PowerShell do not support — in a repo that runs a Windows CI leg. `cross-env`
  would be a new dependency needing an ADR (rule 2) for something ten lines of
  Node already do, so the script moved to `tools/coverage/enforced.mjs`, matching
  the existing `tools/*/check.mjs` convention.

* The `sync:models:check` step I added to the weekly catalog job ran AFTER
  `pnpm sync:models`, which REWRITES `snapshot.ts` in the ephemeral checkout
  (sync.mjs's `writeFileSync`). It therefore compared upstream against the file
  the previous step had just regenerated and would have reported "current" every
  time — an informational step that could never inform. Moved ahead of the guard,
  where it reads the committed snapshot.

* The compiled-binary smoke existed only in `ci.yml`, recreating #312's
  divergence in the opposite direction: the local script this PR exists to align
  still did not run the artifact. Extracted to `tools/cli-smoke/check.mjs` and
  called from both `ci.yml` and the root `ci` script, so the check cannot drift
  out of one of them again.

* The coverage job's own comment still read "Advisory for now … promote to a
  required check once the margin is confirmed stable", contradicting the header
  this PR rewrote and the live branch protection, which now requires
  `engine coverage floor (llm, mcp)`.

* MD028: the authority notice landed flush against the phase-2.5.5 status banner,
  leaving a bare blank line between two blockquotes.

* 2.6.M said dynamic `invoke_workflow` was "moved to 2.6.P", which reads as a
  2.6.P deliverable. It is tracked alongside 2.6.P — whose `subworkflow` node and
  nested-run event namespace are its natural home — but deferred past the phase
  (D57); 2.6.P's ADR records the deferral, not the design.

SKIPPED: the finding that phase-2.5.5's "both required `ci.yml` checks" wording
overclaims. Branch protection already lists both `lint · typecheck · test` and
`engine coverage floor (llm, mcp)`, so the statement is accurate as written.

Verified with the full `pnpm run ci` (green, including the new smoke leg) and by
re-confirming the enforcement split behaviourally: with `core`'s floor raised to
99, `coverage:enforced` passes and `coverage` fails.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…llowed

`tools/coverage/enforced.mjs` never reached the repository. `.gitignore:49`
carries `coverage/` with no leading slash, so it matches a directory of that name
at EVERY depth — `git add -A` skipped the new script without a word, the commit
looked complete, and CI failed with MODULE_NOT_FOUND on a file that exists on
every developer's disk.

Renamed to `tools/coverage-gate/run.mjs`. The two obvious alternatives are both
worse: anchoring the pattern to `/coverage/` would stop ignoring the per-package
`packages/*/coverage` output it exists for, and a `!` negation cannot re-include
a file whose parent directory is excluded.

Verified the file is in the index this time, not merely on disk.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@package.json`:
- Line 30: The db:sync-check script uses POSIX-only shell syntax and is not
cross-platform. Extract its migration-generation and git-status validation into
a Node-based checker such as tools/db-sync/check.mjs, preserving the existing
out-of-sync error and failure behavior, then update the package.json
db:sync-check command to invoke that checker through pnpm.

In `@tools/cli-smoke/check.mjs`:
- Around line 28-33: Update the smoke-test flow around the steps loop and
spawnSync call to resolve BUNDLE and FIXTURE to absolute paths, create a unique
temporary directory for the run, and pass it as the child process cwd so
history.db is isolated. Ensure the temporary directory is removed after all
steps complete, including when a step fails.
- Around line 32-37: Update the spawnSync invocation inside the steps loop to
include a bounded timeout option, and treat timeout termination as a failure
alongside nonzero status. When reporting the failure, include r.error details
when available before exiting, while preserving the existing label, exit status,
and stderr diagnostics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 94356a0f-bf23-4073-b2c0-ba21e2e6dbe6

📥 Commits

Reviewing files that changed from the base of the PR and between 53df0e7 and 81d9887.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • .github/workflows/models-catalog.yml
  • docs/roadmap/phases/phase-2.5.5-hardening-and-remediation.md
  • docs/roadmap/phases/phase-2.6-conversational-authoring.md
  • package.json
  • tools/cli-smoke/check.mjs
🚧 Files skipped from review as they are similar to previous changes (4)
  • .github/workflows/models-catalog.yml
  • docs/roadmap/phases/phase-2.5.5-hardening-and-remediation.md
  • .github/workflows/ci.yml
  • docs/roadmap/phases/phase-2.6-conversational-authoring.md

Comment thread package.json Outdated
Comment thread tools/cli-smoke/check.mjs Outdated
Comment thread tools/cli-smoke/check.mjs Outdated
… Sonar sweep

Four review findings plus a Sonar batch.

* `pnpm smoke:cli` was writing to the developer's REAL `~/.relavium/history.db`.
  The reviewer suggested a temporary cwd; that would not have worked — the path
  is home-relative (`db/open.ts` → `paths.ts` → `os.homedir()`), not
  cwd-relative, and no config overrides that root. `os.homedir()` does honour
  `$HOME` / `%USERPROFILE%`, so the smoke now runs against a `mkdtemp` sandbox
  and removes it in a `finally`. Verified by mtime: the real database is
  untouched across a full `pnpm run ci`. This is the hazard already tracked in
  deferred-tasks.md, reached from a new direction.

* The smoke also used repo-relative paths (broken from any other cwd) and had no
  timeout, so a hung CLI would have sat until the CI job's own 15-minute kill
  with no usable signal. Absolute paths, a 120 s per-step bound, and explicit
  `error` / `signal` / `status` reporting.

* `db:sync-check` was POSIX-only shell (`test -z "$(…)" || { …; }`), the same
  break-on-Windows class as `coverage:enforced`. Extracted to
  `tools/db-sync/check.mjs`, keeping `git status --porcelain` — `git diff` does
  not see an untracked new migration.

* `tools/coverage-gate/run.mjs` spawned a bare `vitest`, resolved through `PATH`
  (Sonar), and needed `shell: true` on Windows to find the `.cmd` shim — two
  injection surfaces for one convenience. It now resolves vitest's own entry
  through the module graph and spawns `process.execPath` with an absolute path:
  no PATH lookup, no shell.

* Deleted `ci.yml`'s reserved Phase-1 conformance lanes and their TODO. All three
  adapters ship and the live nightly lane runs in `models-catalog.yml`, so the
  TODO named work that had already happened elsewhere.

DECLINED — `--ignore-scripts` on the four `pnpm install` steps (8 Sonar findings).
`pnpm.onlyBuiltDependencies` in the root package.json already allowlists the only
two packages permitted to run lifecycle scripts (`better-sqlite3` for its native
prebuild, `esbuild` for its platform binary); every other transitive dependency is
already blocked. Adding the flag would break both and strengthen nothing. The
rationale is now in `ci.yml`'s header so the next sweep does not re-raise it.

ROUTED — the ~30 remaining Sonar findings are in already-merged code outside this
diff, so they go to the existing `Sonar code-quality backlog` in
deferred-tasks.md under that section's own standing policy. Two are called out as
more than cosmetic: `references.ts:154`'s regex has super-linear backtracking on
the `{{ }}` filter-argument path (2.5.5.A scope, not a nit), and
`chat-ink.tsx:1151`'s cognitive complexity of 91 belongs to the god-file 2.5.5.I
deliberately declines to decompose.

Verified with the full `pnpm run ci` — green, including the new smoke leg.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@cemililik
cemililik merged commit 0011c3c into main Jul 29, 2026
13 checks passed
cemililik added a commit that referenced this pull request Jul 29, 2026
…phase tasks done

PR #80 landed the CI-truth batch; this finishes Wave 0's remaining two items and
records the result where the phase documents can be read on their own.

* `#162` — three skills embedded `/Users/dev/Documents/Projects/Agent-Organizer/`,
  a path from an unrelated project. Filed as documentation, but `add-package`'s
  `mkdir -p` would have created a directory tree OUTSIDE the repository, and the
  other two would simply fail. All three now anchor on
  `$(git rev-parse --show-toplevel)`, matching `write-adr` and `commit-and-pr`.

* `#128`/`#129`/`#153`/`#163`/`#254` — `packages/mcp` is a shipped, tested package
  that appeared in none of the five inventory sites. Added to CLAUDE.md's package
  table, project-structure.md's table and diagram, overview.md's diagram and
  package list, and the reviewer agent — the last of which mattered most: its
  checklist never looked at the package, so an ADR-0052 boundary break had no
  reviewer signal.

* `#164` — the reviewer agent's secrets item described only the desktop threat
  model (0% built) and said nothing about the surface that actually ships. Now
  leads with the CLI floor: stdin-not-argv, `0600` on `history.db`/`config.toml`,
  and redaction before anything reaches an approval preview, a run summary, or a
  `--json` payload.

* `#167` — the security-review skill's SSRF step enumerated the ranges to block
  but never required REUSING the shared guard. A hand-rolled second range check is
  how the two drift and one silently stops covering a range (rule 3).

Phase-document bookkeeping: 2.5.5.H is now 8/14 and 2.5.5.F 3/20, each task marked
at its bullet so the phase file stands alone without cross-reading current.md.
Wave 0 is closed; Wave 1 (the three CRITICALs and the cost-cap gaps) is next.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant