Skip to content

docs(mdcode): correct section 7 false claims and rewrite its opening - #434

Merged
libei merged 5 commits into
GoogleCloudPlatform:mainfrom
libei:actions-guide-run-it
Sep 16, 2026
Merged

libei merged 5 commits into
GoogleCloudPlatform:mainfrom
libei:actions-guide-run-it

Conversation

@libei

@libei libei commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

Section 7 of the actions guide, Run it, read against run_action.ts,
judge_store.ts, gemini.ts, loader.ts, commands.ts, agent_tools.ts,
validate.ts, dialect.ts and the demo's commerce.yaml.

Five commits. 1e8f663 carries the claim corrections and the reordering;
5ce6bd9 and a43d9b8 are the opening, written and then cut back; 9a1f11c
and 6ec0225 reduce the paragraph introducing kcmd action run to the one
sentence that introduces it.

Independent of #430 — that lands at line 1503, this is 922–1311. #431 and #432
have since merged and the branch still merges clean; neither touches §7, and
§7 says nothing about generated row keys.

5ce6bd9 + a43d9b8 — the section now says why you would run an action

§7 began by explaining kcmd action list mechanically, so a reader met two
commands before learning what either is for. It now opens the way §2 does:
recap what the reader has, one sentence on what the section is for, then a
single line of counterfactual.

The sections so far declared an action, checked it and published it, and
none of that has put it in front of the database the write lands on. This
section is how you run one there, with arguments you choose, and see what
comes back. Pasting the statements into a SQL console would tell you the DML
is valid; a run is what exercises everything wrapped around it.

The counterfactual holds because a sql action's statements are DML you wrote
by hand for that database — dialect.ts:3-6 says so, and nothing translates or
dialect-checks them. "Everything wrapped around it" is deliberately left for
### What a run does to answer two paragraphs below, rather than previewed
here.

a43d9b8 cut the first draft of this, which justified the claim with two more
clauses and then listed the three things a run decides. That list duplicated
### What a run does, which names resolution, binding and the transaction
properly.

9a1f11c + 6ec0225 — the kcmd action run paragraph

Five sentences became one. Every cut sentence was true; none of them was
carrying the message it appeared to.

"Resolution, binding and the transaction run the same way for any action, so
TransferFunds still shows all three" defended figure 3's choice of a guarded
action as its example — against an objection the reader has not formed, about
a figure they have not reached, naming three steps the next subsection
introduces.

"--profile picks a different one, and push follows the same rule" restates
the flag the guide already introduces for push at line 894, then points at
push as though it were the newer of the two. profiles.md stays linked from
section 1.

"The command line never names a database" negates the sentence before it,
which already says the database comes from the profile's deployment target.

"The TransferFunds line above won't run as printed" reads, to somebody
meeting the command for the first time, as the tool having just printed a
command that doesn't work. A declared constraint stopping a write is what
§2 and §7 exist to show, and it should not arrive as a caveat bolted to the
feature's introduction. ### Why a guarded action is refused already
delivers the same fact as a demonstration, with the error text kcmd prints.

That last sentence was covering a defect rather than reporting one. Figure
3 was captioned "one run of TransferFunds", and TransferFunds is guarded
by a non-advisory expression, so it completes no run. The figure shows the
path a run takes; the caption now says so. This is the only caption change in
the PR.

What is left is the sentence that introduces the command: it performs one of
the listed actions, against the database the profile's deployment target
names.

Two claims in 1e8f663 that turned out wrong

"kcmd refuses a call that an expression guards" is false unqualified.
run_action.ts:513-516 filters on_violation: warn constraints out of the
guard set before the refusal test, so an advisory expression guard warns and
the write proceeds. True of AmountIsPositive, which declares no warn; not
true as a rule. Both statements of it now say non-advisory, and the warn
paragraph reads as the definition of that qualifier rather than as a reversal
arriving four paragraphs after the rule.

"ends every entry with the command line that runs it" is over-broad.
commands.ts:1294-1300 prints a run line only where the profile binds an
executor, and an instruction otherwise.

1e8f663 — claims the code contradicts

the guide said the source says
"the action's guards name the judged rule alone" IssueCredit names four, all judgments — and §7 later says "the demo's four judged guards"
"this constraint declares reject" of CreditMemoNamesAServiceFailure it declares warn; the three captured runs came from toggling the field
resolution SQL WHERE account_id = @ref0 OR name = @ref for "Alice Checking" accountId is an Integer, so bindScalar fails and the key predicate is dropped — as the same passage states three paragraphs later
"Three of the five guards … which is also why they load with the all-judged warning" §2 concludes from that same count that IssueCredit "stays clear of the all-judged warning"
onViolation: warn the YAML key is on_violation (z.enum(VIOLATION_EFFECTS)); onViolation is the internal TS field

Table: each false claim and what the source establishes instead.

1e8f663 — structure

  • The section opened with a kcmd action run invocation it then retracted,
    and a disclaimer paragraph carrying two forward links. Both are gone.
  • Figure 3 moves up under a new ### What a run does, so the three steps
    arrive before a page of detail rather than after it.
  • ### How a row is identified### Which rows a call touches. It had no
    inbound links; #7-run-it, #a-guard-settled-in-words and
    #a-guard-that-reads-a-row do, and are untouched.
  • Figure 3 and table 3 each had a preamble that duplicated their own caption.
  • Two bold leads their own paragraphs refuted are rewritten, and a Status:
    rider is dropped.
  • The bare "section 3" mention is now a link, like the section 2 ones.

1e8f663 — prose

One class recurred: a reduced object-relative standing as the subject, with
the main verb landing late — "a call an expression guards is refused", "a
commit your store refuses wrote nothing", "a predicate the input cannot be
a value of is dropped", "Expression guards the run skipped are reported",
"the expression nothing checked". All unwound. "Nobody wrote that statement:
the judge composed it" no longer contradicts itself inside one line.

Every announced count in the section was audited against its list; all now
hold, including four reads (MAX_READS), 20 rows (DEFAULT_ROW_LIMIT,
matching the LIMIT 21 in the shown wrap), 200 characters
(DEFAULT_CELL_LIMIT), and the demo's nine calls (4 guards × 2 + 1 read).

Fenced blocks

5ce6bd9 and a43d9b8 are prose only — every fenced line is byte-identical.
1e8f663 changes three lines on purpose and leaves every other fenced block
untouched:

-kcmd action run TransferFunds --arg source="Alice Checking" \
-    --arg target=ACC-2 --arg amount=250
-     │           WHERE account_id = @ref0 OR name = @ref LIMIT 2
+     │           WHERE name = @ref LIMIT 2

Two things to watch

§7 says "Nothing in kcmd evaluates an expression against live data today".
#421 falsifies that sentence when it lands.

The action list block shows payments/TransferFunds, while the demo
declares commerce/IssueCredit, so it was built from the guide's own fenced
YAML rather than captured from the demo. Diffing it against a real run of a
rebuilt payments model is worth doing, and is not in this PR.

…ader

Section 7 stated four things the code and the demo YAML contradict:

- "the action's `guards` name the judged rule alone" -- `IssueCredit` names
  four, and section 7 itself later says "the demo's four judged guards".
- "this constraint declares `reject`" of `CreditMemoNamesAServiceFailure`,
  which declares `warn`. The three captured runs came from toggling the
  field, and the text now says so.
- The resolution SQL shown twice for `"Alice Checking"` carried both
  predicates, but `accountId` is an `Integer`, so the key predicate is
  dropped -- as the same passage states three paragraphs later.
- "Three of the five guards ... which is also why they load with the
  all-judged warning", where section 2 concludes from that count that
  `IssueCredit` stays clear of it.

Also `onViolation: warn`, which is the internal field name; the YAML key is
`on_violation`, as the other 21 mentions in the guide have it.

Structure: the section opened on a command it then retracted, and reached
the run's three steps only after a page of detail. Figure 3 now sits under
a `What a run does` heading ahead of the mechanics, `How a row is
identified` becomes `Which rows a call touches` (no inbound links), and the
duplicated preamble-plus-caption on figure 3 and table 3 is gone. Two bold
leads that their own paragraphs refuted are rewritten.

Prose: reduced object-relatives standing as the subject with the main verb
landing late ("a call an expression guards is refused", "a predicate the
input cannot be a value of is dropped", "the expression nothing checked")
are unwound; "Nobody wrote that statement: the judge composed it" no longer
contradicts itself in one line.

Three fenced lines change deliberately: the two-line `kcmd action run`
invocation that the section retracted is gone, and figure 3's resolution
SQL is corrected. Every other fenced block survives byte-identical.
Section 7 began by explaining `kcmd action list` mechanically, so a reader
met two commands before learning what either is for. It now opens on the
reader's position: everything so far declared, checked and published the
action, and none of it put the action in front of the database the write
lands on.

The counterfactual is the part that was missing. A `sql` action's statements
are DML you wrote by hand for that database -- `dialect.ts` says so, and
nothing translates or dialect-checks them -- so you could paste them into a
console yourself. That tells you the DML is valid and nothing else about the
call. Whether a guard stops it, whether an entity-typed argument picks out one
row, and whether a scalar arrives as its declared type are all decided by the
runtime around the statement.

Two claims in the committed text were wrong:

- "kcmd refuses a call that an expression guards" is false unqualified.
  `run_action.ts` filters `on_violation: warn` constraints out of the guard
  set before the refusal test, so an advisory expression guard warns and the
  write proceeds. Both statements of the rule now say non-advisory, and the
  `warn` paragraph reads as the definition of that qualifier rather than as a
  late reversal.

- "ends every entry with the command line that runs it" is over-broad.
  `action list` prints a run line only where the profile binds an executor,
  and an instruction otherwise.

Also states that `action list` reads local files and reaches no database, and
that section 4's checks read your model rather than your store -- the static
validator opens no connection to the action's target.

Prose only: every fenced block is byte-identical.
The previous commit made the value proposition clear and then kept going: two
clauses justifying a claim the reader would have accepted unchallenged, and a
three-item list of what a run decides. The subsection immediately below,
"What a run does", already names resolution, binding and the transaction
properly, so the list summarized material the reader had not reached.

The opening now matches section 2's shape -- recap what the reader has, then
one sentence on what this section is for -- with a single line of
counterfactual after it. "Everything wrapped around it" is left for the next
subsection to answer rather than previewed here.

The `action list` sentence goes back to its original one-sentence form,
keeping only the correction: a run line appears where the profile binds an
executor, not on every entry.

Prose only: every fenced block is byte-identical.
Five sentences became three, and two of the cuts were arguments rather than
information.

"Resolution, binding and the transaction run the same way for any action, so
`TransferFunds` still shows all three" defended figure 3's choice of a guarded
action as its example -- against an objection the reader has not formed, about
a figure they have not reached, naming three steps the next subsection
introduces. Cut.

"`--profile` picks a different one, and push follows the same rule" restates
the flag the guide already introduced for push, and then points at push as
though it were the newer of the two. Cut; `profiles.md` stays linked from
section 1.

What is left is what a reader acts on: the command performs an action, the
database comes from the profile rather than the command line, and the
`TransferFunds` line printed above will be refused because an expression
guards it.

Prose only: every fenced block is byte-identical.
Two sentences went, both true and neither carrying the message it appeared to.

"The command line never names a database" negates the sentence before it,
which already says the database comes from the profile's deployment target.
It emphasises an absence and adds nothing.

"The `TransferFunds` line above won't run as printed" reads, to somebody
meeting the command for the first time, as the tool having just printed a
command that doesn't work. A declared constraint stopping a write is what
sections 2 and 7 exist to show, and attaching it to the feature's
introduction as a caveat is the wrong frame for it. The subsection "Why a
guarded action is refused" already delivers the same fact as a
demonstration, with the error text kcmd actually prints.

That sentence was also covering a defect rather than reporting one. Figure 3
was captioned "one run of `TransferFunds`", while `TransferFunds` is guarded
by an expression and so completes no run. The figure shows the path a run
takes, and the caption now says that.

Prose only: every fenced block is byte-identical.
@libei libei changed the title docs(mdcode): correct section 7 false claims, and order it for a reader docs(mdcode): correct section 7 false claims and rewrite its opening Sep 16, 2026
@libei
libei marked this pull request as ready for review September 16, 2026 06:14
@libei
libei merged commit 0022009 into GoogleCloudPlatform:main Sep 16, 2026
7 checks passed
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