feat(cli): 2.J — create / import / export YAML-lifecycle commands#58
Conversation
…urfaces (PR #56/#57 merged) PR #57 merged 2026-06-27 (the inbound MCP client lane, on the PR #56 @relavium/mcp foundation), so flip 2.R to ✅ Done — the deferred post-merge update per the done-after-merge rule. Updates the four status homes: - CLAUDE.md: the Phase-2 status paragraph — 2.R Done (PR #56 + #57, behind ADR-0034/0052/0053); next pickup is 2.J. - docs/roadmap/current.md: the 2.R lane recorded as landed (foundation PR #56, host wiring/transports/secrets/e2e PR #57) with the residual-hardening pointer; next pickup flipped to 2.J. - docs/roadmap/phases/phase-2-cli.md: the header Status line, the 2.R workstream section header + a shipped summary, the "MCP client live" go/no-go row, the Remaining-build-order status + table, and the backbone bullet — 2.R Done, only 2.J remains in-phase. (The DAG/wave/dependency-matrix planning sections are structural and left as-is.) - README.md: the inbound MCP client added to the landed additive lanes. No code change. 2.R was off the M3 critical path and the Phase-3 go/no-go, so this adds capability without changing the gate posture. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ializeWorkflow (2.J authoring)
The CLI authoring lifecycle (2.J `create`/`import`/`export`) needs to emit a validated
agent document back to deterministic, round-trippable YAML — the agent-file sibling of
the existing `serializeWorkflow` (which only covers workflows). `serializeAgent` mirrors
it (sorted map keys, preserved array order, byte-stable parse→serialize→parse). An agent
document carries no secret VALUES by construction (keys live in the OS keychain; MCP `env`
references a secret only by `{{secrets.*}}` placeholder), so the emitted file is share-safe;
re-serializing from the validated AST additionally drops any authored comments. Exported
from the package index alongside `serializeWorkflow`.
Refs: ADR-0026, ADR-0006, ADR-0029
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e, share-safe)
The first of the 2.J authoring lifecycle commands, on a shared `apps/cli/src/authoring/`
module that the import/create commands will reuse:
- `authoring.ts` — surface-agnostic helpers over git-native YAML under a project
`.relavium/`, reusing the strict core parsers: `detectAndParse` (kind-sniff by
extension hint, else workflow-then-agent, with a typed exit-2 CliError on a doc that
is neither), `resolveById` (find by in-file id across both catalogs; unknown →
exit 2, ambiguous → exit 2), `slugExists`, `catalogPath`/`authoredFileName`,
`readAuthoredFile` (the catalog scan's regular-file + size guards), `writeAuthoredFile`
(atomic `wx`/`w`, EEXIST/EISDIR → exit 2), and `serializeAuthored`.
- `commands/export.ts` — `relavium export <id>` re-serializes the resolved doc from the
VALIDATED AST (`serializeWorkflow`/`serializeAgent`), so the copy drops authored
comments and keeps only `{{secrets.*}}` placeholders — never a resolved secret value
(keys live in the OS keychain). Default target `<id>.<suffix>` in cwd; `--out`/`--force`.
Pure YAML I/O — no keychain/db.
- specs.ts: replace the `export <id>` stub with the real `registerExport`.
Tests cover the workflow + agent happy paths (comment-drop + placeholder-keep), `--out`
+ `--json`, and the exit-2 faults (unknown id, ambiguous id, existing-target-without-force).
Refs: ADR-0026, ADR-0006, ADR-0029
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…he project, validated + deduplicated
`relavium import <path>` parse-validates an external YAML (a malformed file is a clean
exit-2 CliError), rejects an in-file id that already names a same-kind catalog entry
(exit 2 unless --force), and writes the RE-SERIALIZED (canonical, comment-free,
{{secrets.*}}-placeholder-preserving) doc to `.relavium/<workflows|agents>/<id>.<suffix>`.
The kind is taken from the file extension when explicit (`.agent.yaml`/`.relavium.yaml`),
else content-sniffed (workflow then agent). Surface-agnostic — pure YAML I/O over the
shared authoring module; no keychain/db. specs.ts: the `import <path>` stub → registerImport.
Tests cover the agent + bare-.yaml-sniffed-workflow happy paths (comment-drop), the
malformed-file / missing-file / slug-collision exit-2 faults, and --force overwrite.
Refs: ADR-0026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nimal workflow Add `relavium create`, the third 2.J YAML-lifecycle command: an interactive `@clack/prompts` wizard that scaffolds either a new agent (`.agent.yaml`) or a minimal single-agent workflow (`input → agent → output`, `.relavium.yaml`) as plain, git-ready YAML under `.relavium/<agents|workflows>/<id>.<suffix>`. The wizard answers are built into a typed definition and **validated against the `@relavium/shared` schema before any write** (via `buildAuthored` re-parsing the serialized AST), so a bad model/provider/name is the same clean exit-2 `CliError` a `run` would raise. A name colliding with an existing project entry is exit 2 unless `--force`. Surface-agnostic: pure YAML I/O — no keychain, no run state. - `authoring.ts`: `CreateSpec`, the `CreatePrompter` seam, `toSlug`, `buildAuthored`. - `create-prompter.ts`: the clack-backed prompter behind an injectable `ClackCreateDeps` slice (the only clack import on the authoring path), so the gather/cancel/branch flow is unit-tested without a TTY. - `create.ts`: the pure command core — headless guard (no wizard under --json / a non-TTY), cancel → clean exit 0, collision guard, write + confirm. - `specs.ts`: wire `registerCreate`; drop `create` from the stub list. - `run.test.ts`: repoint the stub-command regressions at `init` (still a stub), since `create` is now real. Refs: ADR-0026, ADR-0047 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e shipped commands
The authoring trio (`create` / `import` / `export`) is now live, so flip the
canonical CLI commands home and the secret-handling guarantee to match the
shipped behavior:
- commands.md: move the three out of the "lands at 2.J" status into the live
set; document the `create` wizard (kind → name → provider → model → prompt →
tools, schema-validated before write, TTY-only, `--force` on collision), and
the `import`/`export` canonical re-serialize (kind detection, slug dedup,
cross-catalog id resolution, `--out`/`--json`, why the result is share-safe).
- keychain-and-secrets.md: restate the YAML "never holds a secret" guarantee as
the by-construction `{{secrets.*}}`-references-only rule + the comment-dropping
canonical re-serialize, and cross-link the commands home.
Refs: ADR-0026, ADR-0047
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…, coverage
Address the multi-reviewer pass on the 2.J authoring commands plus an adversarial
verification round that caught the same overclaim class in three more places.
CLI:
- authoring.ts `writeAuthoredFile` now takes a `displayPath` (mirroring
`readAuthoredFile`) — its EEXIST/EISDIR `CliError` messages name a cwd-relative
path, never the absolute fs path. All three callers (create/import/export) pass
`relative(cwd, target)`.
- export.ts emits a cwd-relative path in BOTH human stdout and the `--json`
`{id,kind,path}` record (was absolute) — same shape `import --json` already used.
- create-prompter.ts: export `required` for unit test; document the deliberate
`validate` return-type narrowing (clack's `Validate` also allows `Error`).
- specs.ts: header comment no longer lists create/import/export as stubs (they are
live); only `init` + `budget` remain in STUB_COMMANDS.
Docs — correct a secret-handling overclaim (the MCP `env` map is
`z.record(z.string(), z.string())`, so it accepts literals; the schema does NOT
forbid them). Reword to the accurate framing in every affected home — provider keys
absent *by construction* (no schema field holds a key), MCP `{{secrets.*}}` *by
convention*, export/import re-serialize *faithfully* (no scrub):
- commands.md (the export table cell + the "why it is safe to share" paragraph),
- keychain-and-secrets.md ("what never holds a secret" row),
- workflow-yaml-spec.md (the validation-rules bullet),
- export.ts / authoring.ts module docstrings.
Tests (+6): the bare-`.yaml` agent-sniff and dual-parse-failure branches of
`detectAndParse`; the `required` validator (empty/whitespace/undefined/valid); a
true export→import round-trip into a fresh project; a relative-path assertion on
export `--json`; cwd-absent assertions on the EEXIST + EISDIR write-error arms.
Toolchain: lint/typecheck/test (716) + build green; Leakwatch 0 findings.
Refs: ADR-0006, ADR-0026, ADR-0033, ADR-0047
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Sorry @cemililik, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (10)
🚧 Files skipped from review as they are similar to previous changes (6)
📝 WalkthroughWalkthroughAdds core agent YAML serialization, authoring helpers, interactive create/import/export commands, live CLI registration, and updated docs/status text for the new YAML authoring flow. ChangesYAML Authoring Lifecycle Commands
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Code Review
This pull request implements the YAML-authoring lifecycle (workstream 2.J) by introducing the create, import, and export CLI commands. It adds a shared authoring core for reading, writing, and validating agent and workflow YAML files, along with an interactive @clack/prompts wizard for scaffolding new definitions. The import and export commands allow safe sharing of configurations by re-serializing from the validated AST, which strips comments and preserves secret placeholders. Tests, command registrations, and documentation have been updated accordingly. There are no review comments to address, and I have no additional feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (1)
apps/cli/src/commands/export.test.ts (1)
81-90: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAvoid the unsafe
ascast on parsed JSON.Line 87 bypasses the repo’s strict TS rule in a test that can stay fully typed without it. Parse to
unknownand assert the expected shape with matchers (or a tiny type guard) before readingpath.As per coding guidelines,
**/*.{ts,tsx}: TypeScript-first, strict. Noany, no unsafeas.Proposed fix
- const record = JSON.parse(out().trim()) as { id: string; kind: string; path: string }; - expect(record).toMatchObject({ id: 'reviewer', kind: 'agent' }); - expect(record.path).toBe(join('shared', 'copy.agent.yaml')); // cwd-relative, never the absolute path + const record: unknown = JSON.parse(out().trim()); + expect(record).toEqual( + expect.objectContaining({ + id: 'reviewer', + kind: 'agent', + path: join('shared', 'copy.agent.yaml'), + }), + ); // cwd-relative, never the absolute path🤖 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 `@apps/cli/src/commands/export.test.ts` around lines 81 - 90, The test in exportCommand should not use an unsafe TypeScript cast when parsing JSON output. Update the assertion near exportCommand in export.test.ts to parse the result as unknown, then validate the expected object shape with matcher checks or a small type guard before accessing path, keeping the test fully type-safe without any `as` cast.Source: Coding guidelines
🤖 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 `@apps/cli/src/authoring/create-prompter.ts`:
- Around line 15-19: The select result in ClackCreateDeps and createPrompter is
widened to string | symbol, which drops the option-value union and allows
invalid fallthrough. Update ClackCreateDeps.select to preserve the inferred
option value type from `@clack/prompts`, then adjust createPrompter’s selection
handling to use that narrowed union directly and treat any impossible value as
an error instead of defaulting to 'agent' or null.
In `@apps/cli/src/commands/create.ts`:
- Around line 60-64: The create command’s duplicate check only uses parsed.kind,
which allows the same bare slug to be created in both catalogs and makes shared
exports ambiguous. Update create.ts to enforce uniqueness across both catalogs
by checking the slug against all relevant kinds via the shared helper used by
slugExists or an equivalent centralized lookup, and apply the same cross-catalog
collision rule in importCommand so both paths reject conflicting IDs
consistently.
- Around line 43-47: The create command only checks stdout for interactivity, so
the wizard can still start when stdin is not a TTY and hang in non-interactive
runs. Update the guard in create.ts before createClackPrompter() to also verify
stdin is TTY, preferably through CliIo alongside stdoutIsTty, and keep the
existing invalid_invocation error path for any non-interactive input/output
combination.
In `@CLAUDE.md`:
- Around line 70-72: The rendered guide contains a stray diff marker before the
ADR-0053 reference, so update the relevant paragraph in CLAUDE.md to remove the
leading plus sign and keep the ADR links as plain prose. Locate the line that
mentions ADR-0034, ADR-0052, and ADR-0053, and ensure the text reads cleanly
without any leftover patch notation.
In `@docs/reference/cli/commands.md`:
- Around line 147-149: Update the `create` CLI docs so the validation sentence
reflects the selected kind’s schema rather than only `@relavium/shared`; this
affects the interactive scaffolder description where `kind` can be either an
agent or a minimal single-agent workflow. Mention that the typed definition is
validated against the appropriate schema for `.agent.yaml` or `.relavium.yaml`
before write, and keep the existing references to the `create` flow, `kind`, and
the `.relavium/agents` / `.relavium/workflows` outputs.
---
Nitpick comments:
In `@apps/cli/src/commands/export.test.ts`:
- Around line 81-90: The test in exportCommand should not use an unsafe
TypeScript cast when parsing JSON output. Update the assertion near
exportCommand in export.test.ts to parse the result as unknown, then validate
the expected object shape with matcher checks or a small type guard before
accessing path, keeping the test fully type-safe without any `as` cast.
🪄 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: 14bd4455-645c-47e6-a9ec-bea74e40115f
📒 Files selected for processing (21)
CLAUDE.mdREADME.mdapps/cli/src/authoring/authoring.tsapps/cli/src/authoring/create-prompter.test.tsapps/cli/src/authoring/create-prompter.tsapps/cli/src/commands/create.test.tsapps/cli/src/commands/create.tsapps/cli/src/commands/export.test.tsapps/cli/src/commands/export.tsapps/cli/src/commands/import.test.tsapps/cli/src/commands/import.tsapps/cli/src/commands/specs.tsapps/cli/src/run.test.tsdocs/reference/cli/commands.mddocs/reference/contracts/workflow-yaml-spec.mddocs/reference/desktop/keychain-and-secrets.mddocs/roadmap/current.mddocs/roadmap/phases/phase-2-cli.mdpackages/core/src/export/serializer.test.tspackages/core/src/export/serializer.tspackages/core/src/index.ts
| export function writeAuthoredFile( | ||
| path: string, | ||
| displayPath: string, | ||
| content: string, | ||
| force: boolean, | ||
| ): void { | ||
| try { | ||
| mkdirSync(dirname(path), { recursive: true }); | ||
| writeFileSync(path, content, { encoding: 'utf8', flag: force ? 'w' : 'wx' }); |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file map =="
git ls-files apps/cli/src/authoring | sed 's#^`#-` #'
echo
echo "== outline =="
ast-grep outline apps/cli/src/authoring/authoring.ts --view expanded || true
echo
echo "== relevant slice =="
sed -n '200,320p' apps/cli/src/authoring/authoring.ts
echo
echo "== usages of writeAuthoredFile =="
rg -n "writeAuthoredFile\(" apps/cli/src -A 3 -B 3
echo
echo "== symlink-related helpers in authoring area =="
rg -n "symlink|lstat|statSync|openSync|O_NOFOLLOW|nofollow|force" apps/cli/src/authoring apps/cli/src -A 2 -B 2Repository: HodeTech/Relavium
Length of output: 50373
Reject symlinked write targets. writeFileSync(..., { flag: 'w' }) follows an existing symlink, so a .relavium/... link can redirect create/import/export --force outside the catalog. Open with O_NOFOLLOW (or equivalent) and treat symlink targets as exit 2.
Source: Learnings
| [ADR-0034](docs/decisions/0034-mcp-client-sdk-dependency.md) + [ADR-0052](docs/decisions/0052-inbound-mcp-client-package-lifecycle-registration.md) | ||
| + [ADR-0053](docs/decisions/0053-mcp-network-transport-egress-security.md). 2.R was off the M3 critical path and | ||
| the Phase-3 go/no-go, so it adds capability without gating. The next pickup is **2.J** (the last in-phase additive |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Remove the stray + before the ADR-0053 link.
This looks like an unstripped diff marker and will render awkwardly in the rendered guide.
♻️ Proposed fix
- [ADR-0052](docs/decisions/0052-inbound-mcp-client-package-lifecycle-registration.md) + [ADR-0053](docs/decisions/0053-mcp-network-transport-egress-security.md). 2.R was off the M3 critical path and
+ [ADR-0052](docs/decisions/0052-inbound-mcp-client-package-lifecycle-registration.md) and [ADR-0053](docs/decisions/0053-mcp-network-transport-egress-security.md). 2.R was off the M3 critical path and📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| [ADR-0034](docs/decisions/0034-mcp-client-sdk-dependency.md) + [ADR-0052](docs/decisions/0052-inbound-mcp-client-package-lifecycle-registration.md) | |
| + [ADR-0053](docs/decisions/0053-mcp-network-transport-egress-security.md). 2.R was off the M3 critical path and | |
| the Phase-3 go/no-go, so it adds capability without gating. The next pickup is **2.J** (the last in-phase additive | |
| [ADR-0034](docs/decisions/0034-mcp-client-sdk-dependency.md) + [ADR-0052](docs/decisions/0052-inbound-mcp-client-package-lifecycle-registration.md) and [ADR-0053](docs/decisions/0053-mcp-network-transport-egress-security.md). 2.R was off the M3 critical path and | |
| the Phase-3 go/no-go, so it adds capability without gating. The next pickup is **2.J** (the last in-phase additive |
🤖 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 `@CLAUDE.md` around lines 70 - 72, The rendered guide contains a stray diff
marker before the ADR-0053 reference, so update the relevant paragraph in
CLAUDE.md to remove the leading plus sign and keep the ADR links as plain prose.
Locate the line that mentions ADR-0034, ADR-0052, and ADR-0053, and ensure the
text reads cleanly without any leftover patch notation.
…-TTY guard, select narrowing Address the PR #58 review round: - authoring.ts: add `assertSlugAvailable`, a shared id-uniqueness guard for both `create` and `import`. An id is a PROJECT-GLOBAL handle (`resolveById` / `export <id>` resolve a bare id across BOTH catalogs), so a slug must be unique across agents AND workflows — a same-kind clash needs `--force`, a cross-kind clash is always rejected (a forced overwrite of one kind would leave the other file and make `export <id>` permanently ambiguous). Replaces the per-kind `slugExists` check in create.ts + import.ts, closing the create-both-then-export-ambiguous gap. - io.ts: add `stdinIsTty` to the `CliIo` seam (wired in `processIo` + `captureIo`); `create` now guards on BOTH stdout and stdin being a TTY — a non-TTY stdin makes `@clack/prompts` raw-mode setup throw, so it fails loud (exit 2) rather than crash. - create-prompter.ts: derive the wizard `kind` by matching each option explicitly (symmetric with the provider narrowing) instead of a silent default-to-`agent`. - export.test.ts: parse the `--json` record as `unknown` + `toMatchObject` (drop the unsafe `as` cast). create.test.ts: `toHaveLength(1)` for the inline-agent assertion. - commands.md: document the cross-catalog uniqueness rule, the dual-TTY requirement, and the kind-appropriate schema (agent vs workflow) the wizard validates against. Tests (+3): cross-kind collision rejection in create + import (both `--force` modes), and the non-TTY-stdin guard. Skipped the CLAUDE.md "stray +" finding — it is the ADR-joining separator ("ADR-0034 + ADR-0052 + ADR-0053"), not a diff marker. Toolchain: lint/typecheck/test (719) + build green; Leakwatch 0 findings. Refs: ADR-0026, ADR-0047 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
PR #58 merged 2.J (the create/import/export authoring lifecycle) — the last in-phase workstream — so the in-phase CLI is feature-complete. - phase-2-cli.md: flip 2.J ✅ Done (PR #58) with an as-built reconcile note (agent-or-minimal-workflow create, re-serialize-from-AST share-safety, project- global id uniqueness); mark the phase Status ✅ Complete and reconcile every status surface (banner, milestones table, remaining-build-order, pickup queue, risks) to "every Phase-2 workstream merged". - current.md: add the 2.J landed entry, flip the active-phase line to feature-complete (v0.1.1), refresh the date. (Forward-looking roadmap reshape is left to the concurrent Phase-2.5/2.6 work.) - README.md: add the authoring lifecycle to the Status section and flip "underway" → feature-complete; add a concise agent-first **Getting started** (provider key → `relavium chat` → `/export` → `relavium run`) with an honest note that the public npm publish is the pending final maintainer step of v0.1.1. - Release v0.1.1: bump apps/cli/package.json 0.1.0 → 0.1.1, add CHANGELOG.md (0.1.1 = the three additive lanes 2.S/2.M–2.Q/2.R + 2.J authoring; 0.1.0 = the spine), and ship the changelog in the published tarball (files allowlist). Release flow per release-a-surface.md: tag `v0.1.1` → the `Release CLI` workflow (pack → cross-OS smoke → publish), maintainer-gated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>



What
Phase-2 workstream 2.J — the three surface-agnostic YAML-lifecycle commands that round out the in-phase CLI authoring lane. All read/write git-native YAML under
.relavium/only — never the keychain or run state.relavium create [--force]@clack/promptswizard scaffolding an agent (.agent.yaml) or a minimal single-agent workflow (input → agent → output,.relavium.yaml). Answers are validated against the@relavium/sharedschema before write — a bad model/provider/name is the same clean exit-2CliErrorarunraises. TTY-only (fails loud under--json/non-TTY); cancel writes nothing, exits 0.relavium import <path> [--force]--force).relavium export <id> [--out <path>] [--force]<id>resolved across both catalogs (unknown/ambiguous → exit 2);--json→{id,kind,path}(cwd-relative).Adds
serializeAgentto@relavium/core(the.agent.yamlcounterpart ofserializeWorkflow).Acceptance met: create produces a schema-valid file that subsequently runs; import rejects malformed/slug-colliding with exit 2; export carries no secret material and re-imports cleanly (asserted as a true round-trip).
Share-safety model (corrected)
A provider API key is never in the file by construction (no schema field holds a key value — keys live in the OS keychain). MCP-server secrets are referenced via
{{secrets.*}}placeholders by convention — theenvmap isz.record(string,string), so export/import re-serialize faithfully (they do not scrub); the comment-drop is additional hardening. The reference docs (commands.md,keychain-and-secrets.md,workflow-yaml-spec.md) were corrected to state this accurately rather than overclaim a schema-level guarantee.Review
Three independent
relavium-reviewerpasses (0 blockers) + an adversarial verification workflow (4 lenses + completeness critic) over the fix diff. The critic caught that the secret-doc correction was only partly applied — the same overclaim survived in 3 more homes — all folded into the review-fix commit. Path-display hygiene (no absolute fs path in any error/--json), seam/engine-purity/secret-safety, and would-fail-on-revert tests all confirmed.Toolchain
pnpm turbo run lint typecheck test buildgreen (716 CLI tests); Leakwatch 0 findings; no new runtime dependency.Note
Also carries
28883ad— the 2.R roadmap ✅-flip (a post-merge doc commit from PR #56/#57 that hadn't yet been PR'd tomain). The 2.J roadmap flip is deferred to a separate post-merge commit per project convention.Refs: ADR-0006, ADR-0026, ADR-0033, ADR-0047
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
relavium create,relavium import, andrelavium exportcommands for YAML-based workflows/agents.--force,--out, and--jsonoutput.Bug Fixes
{{secrets.*}}placeholders while dropping authored comments.Documentation