Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lexicons/aws/docs/pages/policy-validation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default Op({
// (`chant build src --lexicon aws -o template.json`).
phase("Build", [build(".")]),
// Runs `cfn-guard validate -r rules.guard -d template.json`.
// A violation fails the workflow here, so nothing is applied.
// A violation fails the run here, so nothing is applied.
phase("Policy", [guardValidate("rules.guard")]),
phase("Apply", [awsApply("template.json", { stackName: "prod" })]),
],
Expand Down
2 changes: 1 addition & 1 deletion lexicons/aws/docs/src/content/docs/policy-validation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default Op({
// (`chant build src --lexicon aws -o template.json`).
phase("Build", [build(".")]),
// Runs `cfn-guard validate -r rules.guard -d template.json`.
// A violation fails the workflow here, so nothing is applied.
// A violation fails the run here, so nothing is applied.
phase("Policy", [guardValidate("rules.guard")]),
phase("Apply", [awsApply("template.json", { stackName: "prod" })]),
],
Expand Down
9 changes: 5 additions & 4 deletions lexicons/aws/src/agentcore/trace-fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
* lexicon contributes `dogwoodReplay`: a plain exported async function taking
* one args object, re-exported from `src/op/activities/index.ts`, resolved **by
* name** by core's activity registry when a project lists the `aws` lexicon.
* No Temporal import beneath it, so the local executor runs it unchanged and a
* Temporal worker registers the same function. Transport is injectable through
* the same `AwsReadHttp` seam `src/api/read-client.ts` already uses, so tests
* never touch the network and `endpoint` retargets the whole thing.
* It imports no runtime of its own, so the local executor
* (`packages/core/src/op/local-executor.ts`) calls it as-is. Transport is
* injectable through the same `AwsReadHttp` seam `src/api/read-client.ts`
* already uses, so tests never touch the network and `endpoint` retargets the
* whole thing.
*
* The output is text. The cedar lexicon's `PolicyReplayOp` reads a trace from
* `tracePath`, so `outPath` here is the handoff — and it is the *only* handoff.
Expand Down
5 changes: 3 additions & 2 deletions lexicons/aws/src/op/activities/floci.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ export function flociRunCommand(args: FlociUpArgs = {}): string {
* Idempotent: reuses a running container of the same name. Waits for the health
* endpoint to report `readyService`, then sets `AWS_ENDPOINT_URL` + test creds in
* the process environment so a following `nativeApply`/`cfn-deploy` targets the
* emulator. Env injection assumes the in-process local executor; under a
* distributed Temporal worker, pass the endpoint explicitly instead.
* emulator. Env injection works because the local executor runs every step of a
* run in this process; a step that runs anywhere else needs the endpoint passed
* to it explicitly.
*/
export async function flociUp(args: FlociUpArgs = {}, signal?: AbortSignal): Promise<{ endpoint: string }> {
const region = args.region ?? DEFAULT_REGION;
Expand Down
21 changes: 16 additions & 5 deletions lexicons/cedar/docs/pages/dogwood-replay.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,22 @@ markdown, and the other two hand back a title and body for whatever opens them
division `workflowSupplyChainAudit` draws. `failOnDivergence` defaults to
false: an observe-dial Op reports, and a red run is the caller's decision.

The composite ships from cedar, not from temporal, because it hands back an Op
and nothing else. It imports `@intentius/chant/op` and carries no dependency on
the temporal lexicon. A project that wants it scheduled pairs it with a
`TemporalSchedule` of its own — two lines, project-side, rather than a config
flag that would drag the dependency in for everyone.
The composite ships from cedar because it hands back an Op and nothing else. It
imports `@intentius/chant/op` and depends on no other lexicon.

A project that wants it scheduled sets `schedule` on the composite (#2120). The
string lands on the Op as `schedule: { cron, overlap: "skip" }`, which is
runtime-neutral data each reader interprets: `chant operator` ticks it locally,
the github/gitlab/forgejo lexicons render it as a CI cron, and the one-shot
executor behind `chant run policy-replay` ignores it.

```typescript
export const { op } = PolicyReplayOp({
name: "policy-replay",
schedule: "0 6 * * *",
// …
});
```

## Typed traces

Expand Down
21 changes: 16 additions & 5 deletions lexicons/cedar/docs/src/content/docs/dogwood-replay.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,22 @@ markdown, and the other two hand back a title and body for whatever opens them
division `workflowSupplyChainAudit` draws. `failOnDivergence` defaults to
false: an observe-dial Op reports, and a red run is the caller's decision.

The composite ships from cedar, not from temporal, because it hands back an Op
and nothing else. It imports `@intentius/chant/op` and carries no dependency on
the temporal lexicon. A project that wants it scheduled pairs it with a
`TemporalSchedule` of its own — two lines, project-side, rather than a config
flag that would drag the dependency in for everyone.
The composite ships from cedar because it hands back an Op and nothing else. It
imports `@intentius/chant/op` and depends on no other lexicon.

A project that wants it scheduled sets `schedule` on the composite (#2120). The
string lands on the Op as `schedule: { cron, overlap: "skip" }`, which is
runtime-neutral data each reader interprets: `chant operator` ticks it locally,
the github/gitlab/forgejo lexicons render it as a CI cron, and the one-shot
executor behind `chant run policy-replay` ignores it.

```typescript
export const { op } = PolicyReplayOp({
name: "policy-replay",
schedule: "0 6 * * *",
// …
});
```

## Typed traces

Expand Down
5 changes: 2 additions & 3 deletions lexicons/cedar/src/dogwood/replay-activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
* Contributed the way the fly lexicon contributes `flyApply`: a plain exported
* async function taking one args object, re-exported from
* `src/op/activities/index.ts`, resolved **by name** by core's activity
* registry when a project lists the `cedar` lexicon. There is no Temporal
* import here and no Temporal dependency in the package — the local executor
* runs it as-is, and a Temporal worker registers the same function.
* registry when a project lists the `cedar` lexicon. It imports no runtime of
* its own, so the local executor calls it as-is.
*
* What it does: takes a policy bundle (inline text or paths), an event trace
* (typed events, inline text, or a path) and a set of expectations, runs
Expand Down
4 changes: 2 additions & 2 deletions lexicons/cedar/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ export { DOGWOOD_UPSTREAM } from "./dogwood/upstream";

// The replay Op composite and its typed step builders (#1661). Flat, like
// fly's `flyDeploy`: an Op factory is what a project's `ops/*.op.ts` names,
// and it carries no dependency on the temporal lexicon — see
// ./dogwood/replay-op.ts for why the composite ships from cedar.
// and it depends on no lexicon but this one — see ./dogwood/replay-op.ts for
// why the composite ships from cedar.
export {
DEFAULT_REPLAY_REPORT_PATH,
PolicyReplayOp,
Expand Down
4 changes: 2 additions & 2 deletions lexicons/cedar/src/op/activities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
* being registered as activities nobody would ever name in a step.
*
* Contributed the `flyApply` way: a plain async function taking one args
* object, with no Temporal import anywhere beneath it, so the local executor
* runs it unchanged and a Temporal worker registers the same function.
* object, depending on no runtime beyond node, so the local executor
* (`packages/core/src/op/local-executor.ts`) calls it directly.
*/

export { dogwoodReplay, dogwoodReplayReport } from "../../dogwood/replay-activity";
Expand Down
7 changes: 5 additions & 2 deletions lexicons/cedar/src/skills/chant-cedar-dogwood.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,11 @@ Three phases — Artifacts (`chantBuild`, skippable with `buildScript: false`),
Replay (`dogwoodReplay`, writes `dist/dogwood-replay.json`), Report
(`dogwoodReplayReport`, acts on `report | issue | pull-request`).
`failOnDivergence` defaults to false: an observe-dial Op reports. The composite
ships from cedar and carries no dependency on the temporal lexicon; a scheduled
form is a project-side `TemporalSchedule` pairing.
ships from cedar; it imports `@intentius/chant/op` and nothing else. Cadence is
a `schedule` on the Op itself (#2120): pass `schedule: "0 6 * * *"` and it lands
as `schedule: { cron, overlap: "skip" }`, which `chant operator` ticks locally
and the github/gitlab/forgejo lexicons render as a CI cron. The one-shot
executor behind `chant run` ignores it.

Build traces with `dogwood.traceEvent()` rather than by hand. Two traps it
exists to close, and both are worth naming whenever a user assembles a fixture:
Expand Down
2 changes: 1 addition & 1 deletion lexicons/fountain/docs/pages/composites.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ Three things are refused at construction rather than at apply:
- An op whose `schedule.overlap` is anything but `skip`. A fountain schedule that fires while the teammate is busy is dropped with `teammate was busy`, so any other policy would be a promise the server does not keep.
- A webhook url FTN022 would reject: plaintext http, or a loopback, link-local or RFC1918 target. Refusing here rather than at synth keeps the author from reading a lint error about a resource they never typed.

`chant build` emits all four to the manifest in dependency orderEnvironment, Vault, Agent, Teammate, Schedule, Webhook — and `fountainApply` reconciles them. The first three go through fountain's bulk `POST /api/apply`; the other three, which bulk apply does not carry yet ([fountain#1636](https://github.com/BinaryBourbon/fountain/issues/1636)), go through their own routes afterwards, matched by name and by url, so a second apply of an unchanged manifest makes no writes at all.
`chant build` emits all six to the manifest in dependency order: Environment, Vault, Agent, Teammate, Schedule, Webhook. `fountainApply` reconciles them. The first three go through fountain's bulk `POST /api/apply`, which reports each resource as `created` or `updated` and nothing else, so it cannot tell you an Environment was already right. The other three, which bulk apply does not carry yet ([fountain#1636](https://github.com/BinaryBourbon/fountain/issues/1636)), go through their own routes afterwards, matched by name and by url, reading live state and comparing before they write, so a second apply of an unchanged manifest makes no Teammate, Schedule or Webhook writes.
4 changes: 2 additions & 2 deletions lexicons/fountain/docs/pages/steward.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The teammate's thread is that environment's operational history. Each turn is on

## The mesh

chant needs six things from a place to run ops. fountain already has a noun for each:
chant needs seven things from a place to run ops. fountain already has a noun for each:

| chant need | fountain noun |
|---|---|
Expand Down Expand Up @@ -100,6 +100,6 @@ The composite refuses three things at construction, so the failure arrives while

## What `chant build` emits

All six kinds, in dependency order: Environment, Vault, Agent, Teammate, Schedule, Webhook. `fountainApply` sends the first three through fountain's bulk `POST /api/apply` and the other three through their own routes afterwards, matched by name and by url, so a second apply of an unchanged manifest makes no writes.
All six kinds, in dependency order: Environment, Vault, Agent, Teammate, Schedule, Webhook. `fountainApply` sends the first three through fountain's bulk `POST /api/apply` and the other three through their own routes afterwards, matched by name and by url. Bulk apply reports each resource as `created` or `updated` and nothing else, so an Environment that changed in no way still comes back `updated`. The per-route reconcilers read what is live and compare before they write, so a second apply of an unchanged manifest makes no Teammate, Schedule or Webhook writes.

See [Composites](/chant/lexicons/fountain/composites/) for the constructor's full option list, [Runtime](/chant/lexicons/fountain/runtime/) for running an op on the steward, and [ACP](/chant/lexicons/fountain/acp/) for what the sandbox is actually speaking.
2 changes: 1 addition & 1 deletion lexicons/fountain/docs/src/content/docs/composites.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ Three things are refused at construction rather than at apply:
- An op whose `schedule.overlap` is anything but `skip`. A fountain schedule that fires while the teammate is busy is dropped with `teammate was busy`, so any other policy would be a promise the server does not keep.
- A webhook url FTN022 would reject: plaintext http, or a loopback, link-local or RFC1918 target. Refusing here rather than at synth keeps the author from reading a lint error about a resource they never typed.

`chant build` emits all four to the manifest in dependency orderEnvironment, Vault, Agent, Teammate, Schedule, Webhook — and `fountainApply` reconciles them. The first three go through fountain's bulk `POST /api/apply`; the other three, which bulk apply does not carry yet ([fountain#1636](https://github.com/BinaryBourbon/fountain/issues/1636)), go through their own routes afterwards, matched by name and by url, so a second apply of an unchanged manifest makes no writes at all.
`chant build` emits all six to the manifest in dependency order: Environment, Vault, Agent, Teammate, Schedule, Webhook. `fountainApply` reconciles them. The first three go through fountain's bulk `POST /api/apply`, which reports each resource as `created` or `updated` and nothing else, so it cannot tell you an Environment was already right. The other three, which bulk apply does not carry yet ([fountain#1636](https://github.com/BinaryBourbon/fountain/issues/1636)), go through their own routes afterwards, matched by name and by url, reading live state and comparing before they write, so a second apply of an unchanged manifest makes no Teammate, Schedule or Webhook writes.
4 changes: 2 additions & 2 deletions lexicons/fountain/docs/src/content/docs/steward.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The teammate's thread is that environment's operational history. Each turn is on

## The mesh

chant needs six things from a place to run ops. fountain already has a noun for each:
chant needs seven things from a place to run ops. fountain already has a noun for each:

| chant need | fountain noun |
|---|---|
Expand Down Expand Up @@ -104,6 +104,6 @@ The composite refuses three things at construction, so the failure arrives while

## What `chant build` emits

All six kinds, in dependency order: Environment, Vault, Agent, Teammate, Schedule, Webhook. `fountainApply` sends the first three through fountain's bulk `POST /api/apply` and the other three through their own routes afterwards, matched by name and by url, so a second apply of an unchanged manifest makes no writes.
All six kinds, in dependency order: Environment, Vault, Agent, Teammate, Schedule, Webhook. `fountainApply` sends the first three through fountain's bulk `POST /api/apply` and the other three through their own routes afterwards, matched by name and by url. Bulk apply reports each resource as `created` or `updated` and nothing else, so an Environment that changed in no way still comes back `updated`. The per-route reconcilers read what is live and compare before they write, so a second apply of an unchanged manifest makes no Teammate, Schedule or Webhook writes.

See [Composites](/chant/lexicons/fountain/composites/) for the constructor's full option list, [Runtime](/chant/lexicons/fountain/runtime/) for running an op on the steward, and [ACP](/chant/lexicons/fountain/acp/) for what the sandbox is actually speaking.
4 changes: 2 additions & 2 deletions lexicons/fountain/src/deep-observe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
*
* fountain's JSON views name their fields the same way the request schema does
* (`networking_type`, `env_vars`, `skills`), so the live tree and the declared
* tree already speak one vocabulary — the AWS situation, not temporal's. The
* payload is therefore forwarded as-is and the noise rules
* tree already speak one vocabulary and nothing has to be renamed on the way in.
* The payload is therefore forwarded as-is and the noise rules
* (./deep-observe-hooks.ts) do the rest. A field fountain adds in a later
* release surfaces as unclaimed until the table names it (#2160: source
* never set it, so it is not drift and is never proposed for update), which is
Expand Down
6 changes: 4 additions & 2 deletions lexicons/fountain/src/skills/chant-fountain-ops.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ chant run <apply op> # or call fountainApply directly

`fountainApply` sends Environment, Vault and Agent through fountain's bulk
`POST /api/apply`, then Teammate, Schedule and Webhook through their own routes,
matched by name and by url. A second apply of an unchanged manifest writes
nothing.
matched by name and by url. Bulk apply reports each resource as `created` or
`updated` and nothing else, so it never says a resource was already right. The
per-route reconcilers compare live state before they write, so a second apply of
an unchanged manifest makes no Teammate, Schedule or Webhook writes.

Endpoint and token come from `fountain.profiles` in `chant.config.ts`, falling
back to `FOUNTAIN_ENDPOINT` / `FOUNTAIN_TOKEN`. A profile's `token` is always
Expand Down
2 changes: 1 addition & 1 deletion lexicons/github/docs/pages/lint-rules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ Flags a workflow file with no top-level `on:` key. Without a trigger the workflo

GHA029 onward are a CI/CD supply-chain security pass: pin & vet external references, enforce least-privilege token scopes, guard trust boundaries against untrusted input, contain secrets, reject unsound expressions, and keep artifacts/caches honest. They run statically on the emitted YAML — everything answerable without leaving the build.

The checks that need a *moving external truth* — whether a pinned SHA still maps to a real upstream tag, whether a ref still exists, whether a new advisory now covers an action in use — can't be deterministic, so they live in the operational layer instead. Schedule the [`WorkflowAuditOp`](/chant/guide/ops/#audit-supply-chain-drift) (temporal lexicon) for that live, always-fresh half; it reads the same emitted workflow references and reports drift via `report | issue | pull-request`.
The checks that need a *moving external truth* — whether a pinned SHA still maps to a real upstream tag, whether a ref still exists, whether a new advisory now covers an action in use — can't be deterministic, so they live in the operational layer instead. Schedule the [`WorkflowAuditOp`](/chant/guide/ops/#audit-supply-chain-drift), which ships from core's `@intentius/chant/op`, for that live, always-fresh half; it reads the same emitted workflow references and reports drift via `report | issue | pull-request`.

### GHA029 — Action or reusable workflow not pinned to a commit SHA

Expand Down
2 changes: 1 addition & 1 deletion lexicons/github/docs/src/content/docs/lint-rules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ Flags a workflow file with no top-level `on:` key. Without a trigger the workflo

GHA029 onward are a CI/CD supply-chain security pass: pin & vet external references, enforce least-privilege token scopes, guard trust boundaries against untrusted input, contain secrets, reject unsound expressions, and keep artifacts/caches honest. They run statically on the emitted YAML — everything answerable without leaving the build.

The checks that need a *moving external truth* — whether a pinned SHA still maps to a real upstream tag, whether a ref still exists, whether a new advisory now covers an action in use — can't be deterministic, so they live in the operational layer instead. Schedule the [`WorkflowAuditOp`](/chant/guide/ops/#audit-supply-chain-drift) (temporal lexicon) for that live, always-fresh half; it reads the same emitted workflow references and reports drift via `report | issue | pull-request`.
The checks that need a *moving external truth* — whether a pinned SHA still maps to a real upstream tag, whether a ref still exists, whether a new advisory now covers an action in use — can't be deterministic, so they live in the operational layer instead. Schedule the [`WorkflowAuditOp`](/chant/guide/ops/#audit-supply-chain-drift), which ships from core's `@intentius/chant/op`, for that live, always-fresh half; it reads the same emitted workflow references and reports drift via `report | issue | pull-request`.

### GHA029 — Action or reusable workflow not pinned to a commit SHA

Expand Down
9 changes: 5 additions & 4 deletions lexicons/github/src/components/generate-op-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
* The Op counterpart to `./generate-pipeline.ts` (#891): that module
* synthesizes a `workflow_dispatch`-triggered pipeline from a deploy-time
* component graph, this one synthesizes a cron-triggered workflow per
* stateless Op — the CI-native alternative to a Temporal `TemporalSchedule`
* for downstream projects that don't run Temporal (`WorkflowAuditOp`,
* `PipelineAuditOp`, `ReconcileOp`, … all accept an optional `schedule`
* precisely for this).
* stateless Op. An Op's cadence is an `OpSchedule` on the Op itself
* (`packages/core/src/op/types.ts`), runtime-neutral data each reader
* interprets; this module is the reader that turns it into a cron a GitHub
* runner fires (`WorkflowAuditOp`, `PipelineAuditOp`, `ReconcileOp`, … all
* accept an optional `schedule` precisely for this).
*
* GitHub Actions' `on.schedule` is workflow-scoped, not job-scoped, so unlike
* the component generator (one combined pipeline for the whole graph) this
Expand Down
Loading
Loading