@rosthq/cli 0.7.141 → 0.7.142
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +21 -3
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31855,7 +31855,25 @@ var commandViolationSchema = external_exports.object({
|
|
|
31855
31855
|
/** Advisory human text. Do not parse. */
|
|
31856
31856
|
message: external_exports.string().min(1),
|
|
31857
31857
|
/** The violated bound, when the issue carries one (`max`/`min` on arrays, strings, numbers). */
|
|
31858
|
-
limit: external_exports.number().optional()
|
|
31858
|
+
limit: external_exports.number().optional(),
|
|
31859
|
+
/**
|
|
31860
|
+
* Schema vocabulary describing what was expected — a type name, a declared enum
|
|
31861
|
+
* value set, a format identifier, or a bound direction, FOR EVERY IN-REPO
|
|
31862
|
+
* SCHEMA. It is not structurally guaranteed to stay that way: a `superRefine`
|
|
31863
|
+
* can forge `issue.expected` / `issue.format` from caller data, so the value is
|
|
31864
|
+
* sanitized, capped, and secret-gated (`gateExpected`) before it can reach here
|
|
31865
|
+
* rather than trusted outright. It is never the caller's own parsed VALUE,
|
|
31866
|
+
* which is what `received` describes.
|
|
31867
|
+
*/
|
|
31868
|
+
expected: external_exports.string().optional(),
|
|
31869
|
+
/**
|
|
31870
|
+
* A type descriptor of the caller's own submitted value at the resolved path:
|
|
31871
|
+
* `missing`/`null`/`string`/`number`/`boolean`/`array`/`object`, with counts for
|
|
31872
|
+
* size violations — or, for `unrecognized_keys`, the caller's own unexpected key
|
|
31873
|
+
* NAMES (proven against the payload, secret-gated, capped). NEVER the value
|
|
31874
|
+
* itself (invariant #5).
|
|
31875
|
+
*/
|
|
31876
|
+
received: external_exports.string().optional()
|
|
31859
31877
|
}).strict();
|
|
31860
31878
|
|
|
31861
31879
|
// ../../packages/protocol/src/command-introspection.ts
|
|
@@ -53026,7 +53044,7 @@ When operating through CLI or MCP, create fewer seats first and ask for confirma
|
|
|
53026
53044
|
order: 30,
|
|
53027
53045
|
title: "Charter design playbook",
|
|
53028
53046
|
summary: "How to draft strong Charters that work for human, agent, and hybrid seats.",
|
|
53029
|
-
version: "2026-07-
|
|
53047
|
+
version: "2026-07-31.2",
|
|
53030
53048
|
public: true,
|
|
53031
53049
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
53032
53050
|
stages: ["charter_design", "staffing"],
|
|
@@ -53081,7 +53099,7 @@ List and read first, then draft, then leave activation to a human.
|
|
|
53081
53099
|
|
|
53082
53100
|
- List: \`{{cli}} command charter.list --json '{}'\` or \`rost_list_charters\` (scope: tenant). Read one with \`charter.get\` / \`rost_get_charter\`.
|
|
53083
53101
|
- Draft one: \`{{cli}} command charter.draft --json '{"seat_id":"<seat-id>"}'\` (scope: seat or tenant-admin); draft every eligible seat with \`charter.draft_all\` / \`rost_draft_all_charters\`. Draft commands are not gated \u2014 they produce a draft \`charter_version_id\`. \`charter.draft_all\` drafts every **active or vacant** non-reserved seat \u2014 a vacant seat can receive a conservative draft Charter before it is staffed, since Charters attach to seats, not people, and drafting is not activation: **Charter activation stays a separate, human-gated step** (\`charter.approve\`) whether or not the seat is staffed. Reserved system paths (e.g. \`system.ops\`, Forge role seats) are excluded entirely, before both drafting and skip accounting \u2014 they never appear in \`drafted\`, \`skipped\`, or \`skipped_seats\`. It returns the real result: \`{ drafted, skipped, draft_ids, skipped_seats: [{ seat_id, reason }], effect }\` where \`reason\` is \`seat_not_active\` (the seat is still a graph-authoring draft, not yet active or vacant) or \`charter_exists\` (it already has a draft/active Charter). Read \`skipped_seats\` to see why a freshly-built graph drafted fewer Charters than it has seats \u2014 among non-reserved seats.
|
|
53084
|
-
- **Never read a governed command's success as "it changed something."** Every converted mutating command carries an \`effect\` block \u2014 \`{ attempted, applied, skipped, outcome, skips: [{ target_kind, target_id, reason }], skips_omitted }\`, where \`outcome\` is \`applied\`, \`partial\`, or \`none\`, and \`skips.length + skips_omitted\` always equals \`skipped\` (\`skips\` is capped at 50 entries, so a very large sweep itemises the first 50 and counts the rest \u2014 the arithmetic still adds up) \u2014 so you can branch on it without knowing any one command's field names. **Read it where your surface actually delivers it:** \`response.output.effect\` over HTTP, and \`effect\` on the unwrapped command output in CLI and MCP. (The executor also carries a copy on its internal result envelope, but the HTTP adapter does not re-emit it, so \`response.effect\` is \`undefined\` \u2014 do not read it there.) \`outcome: "none"\` means the call succeeded and changed nothing; \`skips\` tells you why, per target, as stable codes you can branch on rather than prose. Check it and self-correct in the same run instead of reporting a build that did nothing: a second \`charter.draft_all\` over a graph whose seats already have a draft or active Charter returns \`outcome: "none"\` with one \`charter_exists\` skip per seat, and a graph whose seats are still graph-authoring \`draft\` seats returns \`outcome: "none"\` with one \`seat_not_active\` skip per seat. (A freshly built graph of **vacant** seats is not one of these cases \u2014 vacant seats are eligible and do get drafted, per the bullet above.) A **converted** command that skipped work without naming a reason fails its own output validation, so a silent zero-effect success is not a shape *those* commands can return. **This is not yet an API-wide guarantee** \u2014 most mutating commands are not converted yet, and an unconverted bulk or sweep command still returns a bare success that changed nothing: \`confirmation.dismiss_stale\` with no expired confirmations returns \`{ dismissed_count: 0, dismissed_ids: [] }\` with no \`effect\` at all. Treat a missing \`effect\` as "this command cannot tell you", never as "it worked" \u2014 for those, verify against live state before reporting the step done. Input that violates a schema is reported the same way rather than swallowed, naming the offending field path, the stable issue \`code\`, and the violated \`limit\` \u2014 e.g. a 6-principle Compass against \`max(5)\` gives \`{ path: "doc.principles", code: "too_big", limit: 5 }\`. **The field sits at a different place on each surface:** CLI and HTTP callers read it at \`error.details.violations\` (alongside the legacy \`fieldErrors\`), while MCP tool callers read \`violations\` at the **top level** of the error result, next to \`code\` and \`help\` \u2014 MCP results have no \`details\` envelope, so \`details.violations\` is \`undefined\` there.
|
|
53102
|
+
- **Never read a governed command's success as "it changed something."** Every converted mutating command carries an \`effect\` block \u2014 \`{ attempted, applied, skipped, outcome, skips: [{ target_kind, target_id, reason }], skips_omitted }\`, where \`outcome\` is \`applied\`, \`partial\`, or \`none\`, and \`skips.length + skips_omitted\` always equals \`skipped\` (\`skips\` is capped at 50 entries, so a very large sweep itemises the first 50 and counts the rest \u2014 the arithmetic still adds up) \u2014 so you can branch on it without knowing any one command's field names. **Read it where your surface actually delivers it:** \`response.output.effect\` over HTTP, and \`effect\` on the unwrapped command output in CLI and MCP. (The executor also carries a copy on its internal result envelope, but the HTTP adapter does not re-emit it, so \`response.effect\` is \`undefined\` \u2014 do not read it there.) \`outcome: "none"\` means the call succeeded and changed nothing; \`skips\` tells you why, per target, as stable codes you can branch on rather than prose. Check it and self-correct in the same run instead of reporting a build that did nothing: a second \`charter.draft_all\` over a graph whose seats already have a draft or active Charter returns \`outcome: "none"\` with one \`charter_exists\` skip per seat, and a graph whose seats are still graph-authoring \`draft\` seats returns \`outcome: "none"\` with one \`seat_not_active\` skip per seat. (A freshly built graph of **vacant** seats is not one of these cases \u2014 vacant seats are eligible and do get drafted, per the bullet above.) A **converted** command that skipped work without naming a reason fails its own output validation, so a silent zero-effect success is not a shape *those* commands can return. **This is not yet an API-wide guarantee** \u2014 most mutating commands are not converted yet, and an unconverted bulk or sweep command still returns a bare success that changed nothing: \`confirmation.dismiss_stale\` with no expired confirmations returns \`{ dismissed_count: 0, dismissed_ids: [] }\` with no \`effect\` at all. Treat a missing \`effect\` as "this command cannot tell you", never as "it worked" \u2014 for those, verify against live state before reporting the step done. Input that violates a schema is reported the same way rather than swallowed, naming the offending field path, the stable issue \`code\`, and the violated \`limit\` \u2014 e.g. a 6-principle Compass against \`max(5)\` gives \`{ path: "doc.principles", code: "too_big", limit: 5, expected: "<= 5", received: "array (6 items)" }\`. Each violation also carries \`expected\` (what the schema declares at that spot \u2014 a type, format, allowed values, or bound; for a cross-field or business-rule check it is the fixed marker \`a value satisfying the schema's custom check (see message)\`, telling you to read \`message\` for the authored specifics) and \`received\` (the KIND of value you sent \u2014 \`string\`, \`number\`, \`array (6 items)\`, \`missing\` \u2014 or, for undeclared extra keys, their proven, secret-gated names \u2014 never the value itself). **The field sits at a different place on each surface:** CLI and HTTP callers read it at \`error.details.violations\` (alongside the legacy \`fieldErrors\`), while MCP tool callers read \`violations\` at the **top level** of the error result, next to \`code\` and \`help\` \u2014 MCP results have no \`details\` envelope, so \`details.violations\` is \`undefined\` there. Paths are real JSON paths into YOUR OWN submitted payload: a caller-supplied key (e.g. inside a \`capabilities\` or \`headers\` map) is echoed exactly, and an array position reports as \`xs[3].on\`, because a path into input you supplied tells you nothing you do not already hold. A segment shows as \`*\` only when the server could not prove it walks your payload \u2014 a segment no schema declares and your payload does not contain (a refinement can report a path that was never in your input) \u2014 or when the segment name is itself credential-shaped and withheld as secret material. So read \`*\` as **"withheld, unproven"**, not as "this was your key" \u2014 the field names around it are still exact, and the \`code\` still tells you which constraint failed. \`limit\` is likewise only present when the schema itself declares that bound, so its absence means "not proven", not "no bound". The error envelope's \`help\` names the exact next step \u2014 \`rost command schema <id>\` prints the full input contract, and when the payload came from \`--input-file\`, fix the file and re-run it.
|
|
53085
53103
|
- Edit a draft: \`charter.update_draft\` / \`rost_update_charter_draft\` with the \`charter_version_id\` and the new \`doc\`.
|
|
53086
53104
|
|
|
53087
53105
|
In the app, \`/charters\` is both a drafting queue and a governance library. It shows active Charters, draft amendments, seats missing Charters, unsigned manifests, and steward-review gaps. \`/charters/builder\` is the seat picker for Charter Builder: start there when you need to draft a missing Charter, continue an amendment, or review which seats are still missing operating contracts. Opening a live Charter is a review mode: read the active version, inspect its governance state, and open an amendment draft when the job needs to change. Active Charter content is never silently edited in place. Both \`charter.draft_all\` triggers on this page \u2014 the "Draft missing Charters" empty-queue card and the "Draft gaps" header CTA \u2014 render the run's \`effect\` distinctly rather than a bare success: a full run (\`outcome: "applied"\`) shows an ordinary "Done" state, a run that skipped some seats (\`"partial"\`) shows "Partial effect" plus how many seats were skipped and why (the app aggregates them into product copy \u2014 "17 skipped: seat not active" \u2014 while CLI and MCP callers still get the per-target \`target_id\`/\`reason\` values from the contract), and a run that drafted nothing (\`"none"\`) shows "No effect" the same way \u2014 so a human running this from the UI gets the same self-correction signal the effect contract gives a CLI/MCP/HTTP caller, above.
|