Expand description
Composite secrets (Phase 24.1) — one value with secrets inside it.
The motivating case is a calendar-sharing URL,
https://outlook.office365.com/owa/calendar/{mailbox_id}@inf.elte.hu/{calendar_key}/calendar.ics,
where two path segments are credentials and the rest is structure. The
root is the template; each placeholder is a part. Parts are
ordinary extra_vars — see the design note in src/ts/composite.rs’s
TypeScript twin (src/ts/composite.ts) for why a second array was
rejected. This module renders the template against a set of parts and does
nothing else: it does not know about VaultEntry, redaction, or ${…}
references.
This is a twin pair with src/ts/composite.ts, pinned by
tests/fixtures/parity/composite.json — the form needs a live preview, so
rendering exists in both languages, and two implementations of one
template language drift silently if nothing asserts they agree.
§Encoding — decided 2026-09-14
A URL is several zones with different reserved characters, and a value
inserted raw can change what the URL means
(postgres://app:p@ss@db/prod parses with host ss@db). So: parts are
stored raw (the vault holds the credential the issuer gave), and the
renderer classifies each placeholder by the zone it sits in — from a parse
of the template text, not of a URL built from real values — and
percent-encodes accordingly. custom never encodes: the preview shows the
encoded result, so what is copied is what was seen.
The encoder implements exactly RFC 3986’s unreserved set
(ALPHA / DIGIT / "-" / "." / "_" / "~") rather than delegating to a
JS/Rust built-in — encodeURIComponent and this module must byte-for-byte
agree, and the built-ins on the two sides do not use the same unreserved
set (JS additionally leaves ! ~ * ' ( ) unescaped).
Structs§
- Part
- One named
{part}and the raw value it holds. - Rendered
- The result of a successful render: the text, and which parts were used.
Enums§
- Kind
- What a composite template is, which decides its encoding and whether an
Open action is offered. Open past the four presets, the same
open-vocabulary reasoning as
primary_role. - Render
Error - What went wrong rendering a template.
Displaygives the user-facing text.
Functions§
- placeholders
- The placeholder names a template references, without needing any parts — used by the form to build “Make part” suggestions and by the health scan to find orphaned parts, without rendering (and therefore without needing every part filled in first).
- render
- Renders
templateagainstparts, refusing on any unfilled placeholder, unbalanced brace, or (for a URL-shaped kind) a control character in a part.