Skip to content

record

The record commands send a security assessment from your machine to your organization’s platform, so the threats a change introduced, what the team decided about them, and whether the change was verified all end up in one place.

The assessment itself is produced by the ingrain-security skill, which writes it to .ingrain-security/assessment-<branch>-<task>.md. The skill knows nothing about the wire contract — this command is the only place that does.

Terminal window
ingrain record design --assessment <path>
ingrain record verification --assessment <path>

One file, one flag. The org rules the review retrieved ride in the assessment’s own ## Org rules section, so there is no second path to pass. (A --rules sidecar was once required alongside; it is gone, and so is the failure it created — omitting it produced a sync that silently recorded no rule at all.)

They are deliberately not one call. They fire at different moments, carry different data, and fail differently — and either can happen without the other.

record designrecord verification
Fires atdesign-time finalize, after the selection gatesverification finalize, after the code is written and judged
Carriesthreats with their gate decisions, the gated org-rule set, risk, and the implementation guidance with the drivers each entry namesa robustness verdict per selected threat, an adherence verdict per selected rule
Targetsa new assessment revision for this unit of worka new verification record bound to the revision it judged
Re-runsupersedes the prior revision; history is keptsupersedes the prior verdict set; the analysis is untouched
Alone?yes — an unverified analysis is the normal mid-flight stateonly against an existing revision

Sends the analysis as a new assessment revision.

Terminal window
ingrain record design \
--assessment .ingrain-security/assessment-feature-auth-add-rotation.md

Two driver axes and one vessel between them.

  • Threats, each with the decision made at the threat gate: act on it, or accept the risk. Excluded threats travel too — “we saw it and chose not to act” is exactly what a security record should preserve.
  • Org rules, each with the decision made at the rule gate: it governs this change, or it was deemed inapplicable here. Both halves travel, for the same reason: an exclusion is a recorded decision the rule’s author gets to see, and filtering it out would make developer-side scoping silent.
  • Implementation guidance — how a driver’s goal is reached. It carries no decision and no verdict of its own; its efficacy is read off the drivers beside it.

Every guidance entry names at least one driver — a threat it closes, a rule it implements, or both. Work that traces to no stated goal cannot be attributed, verified or governed, so an unanchored entry is refused rather than synced. One entry may serve several threats and several rules at once, and travels once naming them all.

A Rule refs id may only name a rule the gate accepted. Driving a rule that was excluded, or one never gated, claims a mandate nobody granted — and the rule would be unjudgeable at verification, where scope is the accepted set. Both are refused.

A change triaged as not security-relevant is recorded as such, and never replaces an assessment that already exists — the command skips the push and says so rather than overwriting a real analysis with an empty one.

Sends the verdicts against the revision they judged.

Terminal window
ingrain record verification \
--assessment .ingrain-security/assessment-feature-auth-add-rotation.md

Requires a design sync to have run first: a verdict with no analysis to describe is meaningless, so with no revision recorded this fails with a message telling you to run record design rather than inventing one.

A verification has exactly two subjects: the threat and the rule. A robustness verdict per threat the threat gate selected, and an adherence verdict per rule the rule gate accepted — including a rule no guidance ended up implementing, which is precisely the case a security owner needs judged. A rule that was excluded is left unjudged: deemed inapplicable is a recorded decision, never a verdict.

Guidance is never a subject, so nothing is sent about it.

A partial verdict set is accepted. One verdict per accepted rule is the review’s own procedure, not a wire requirement — rejecting a mid-run pass would lose the verdicts it did conclude, and the platform reads an unjudged rule as exactly that.

A unit of work is repository + branch + task title, normalised to a sync key:

<repository>/<branch>/<task>

The repository comes from your git remote, the branch from git, and the task from the assessment’s ## Task → Title. Each segment is lowercased and reduced to [a-z0-9-], so Feature/Design_Sync and feature-design-sync name the same branch — two developers working one branch converge on one record, which is the intent.

If someone else records an assessment for the same unit of work while yours is syncing, the platform rejects the stale handle. The CLI re-pulls and retries once, then stops with a message naming the situation.

record reads the same [context] section as context:

[context]
syncUrl = "https://api.example.com/ingrain-agent-sync"
ingrainApiToken = "ingrn_…"

or INGRAIN_SYNC_URL / INGRAIN_API_TOKEN.

That section is resolved from your user-level conf.toml and the environment — those two, wherever you run the command from. The environment is trusted by design; see Configuration overview for what that means.

CodeMeaning
0Synced.
1The assessment did not validate, or the sync failed.
2Bad arguments — a missing --assessment, a retired flag, or a file that is not there.

To see what is wrong with a file without needing credentials or a network, use ingrain validate. It runs the same parser and the same schemas, so a file it accepts is a file record will send.