Graft provides four read operations: graft_get(),
graft_find(), graft_query(), and
graft_history(). graft_snapshot() captures an
accepted boundary, and graft_at() binds it to a read-only
view that those operations can use. graft_view_snapshot()
recovers the exact path-free boundary retained by a view.
graft_history() uses the exact contract recorded for each
revision. None exposes raw SQL or a mutation path.
| Need | Function | Result |
|---|---|---|
| One current record | graft_get() |
The record and its accepted context |
| Search public fields | graft_find() |
Ranked, bounded matches |
| A fixed advanced operation | graft_query() |
A validated operation-specific result |
| Accepted revisions | graft_history() |
Newest-first immutable history |
| A pinned accepted boundary |
graft_snapshot(), graft_at()
|
A serializable reference and live read view |
| A view’s retained boundary | graft_view_snapshot() |
An isolated copy of the exact pinned snapshot |
| Read-only agent access | graft_tools() |
Tool definitions backed by the same reads |
Create some accepted knowledge
This example uses the resolved data-dict contract included with Graft. It describes people, organizations, and employment records that refer to both. The foreign keys are checked during planning, but they are not semantic graph edges.
library(graft)
schema <- graft_schema(system.file(
"extdata",
"team-directory.data-dict.json",
package = "graft",
mustWork = TRUE
))
store <- graft_open(schema, ":memory:", okf = "disabled")
graft_ingest(
store,
list(
organization = data.frame(
id = "org:daily-planet",
name = "Daily Planet"
),
person = data.frame(
id = "person:lois-lane",
full_name = "Lois Lane",
job_title = "Reporter"
),
employment = data.frame(
id = "employment:lois-lane:daily-planet",
person_id = "person:lois-lane",
organization_id = "org:daily-planet"
)
),
graft_provenance(
producer = "team-directory-import",
idempotency_key = "team-directory-v1"
)
)Pin the accepted boundary
Capture a serializable reference before starting work that must use
fixed accepted knowledge. The reference contains store, schema, and
commit identity, not a filesystem path or live connection.
graft_at() binds it to the open store as a read-only
view:
snapshot <- graft_snapshot(store)
view <- graft_at(store, snapshot)
retained_snapshot <- graft_view_snapshot(view)retained_snapshot has the same identity as
snapshot and remains path-free. Later commits do not change
it or reads through view.
Get one current record
Use graft_get() when the stable identifier is already
known:
person <- graft_get(store, "person:lois-lane")
person$recordThe result includes its class and accepted context. A missing identifier raises a typed package error; callers do not need to know how the record is stored internally.
Find records by public text
Use graft_find() when you know a name or phrase rather
than an identifier:
graft_find(store, "Lois", class = "person", limit = 10)
graft_find(store, "Daily", class = "organization", limit = 10)The compiled contract determines which fields are searchable and which are sensitive. An optional class restriction narrows the search; every call remains bounded by its result limit.
Recover accepted history
Accept a later version of the same person:
graft_ingest(
store,
list(
person = data.frame(
id = "person:lois-lane",
full_name = "Lois Lane",
job_title = "Investigative reporter"
)
),
graft_provenance(
producer = "team-directory-import",
idempotency_key = "team-directory-v2"
)
)The live store now returns the update, while the view remains at the accepted boundary captured above:
graft_get(store, "person:lois-lane")$record$job_title
graft_get(view, "person:lois-lane")$record$job_titlegraft_history() returns the accepted revisions in
newest-first order:
history <- graft_history(
store,
id = "person:lois-lane",
limit = 100
)
history[, c("batch_id", "changed_fields", "record")]An accepted batch ID or POSIXt value selects state at an
exact commit boundary. Commit order, rather than a timestamp inside the
domain record, defines that boundary.
Use fixed advanced operations
graft_query() accepts named operations with validated
request shapes. For example, the integrity operation checks the revision
chain and, when requested, its derived projections:
graft_query(
store,
operation = "integrity",
request = list(projections = TRUE),
limit = 100
)The neighbors operation returns semantic edges only when
the active contract declares graph-producing semantic statements or
edges. Graft does not turn the team directory’s data-dict foreign keys,
or an ordinary LinkML object-reference slot, into traversal edges. See
Add graph semantics with LinkML for
that contract shape.
Other fixed operations cover exact identifiers, claims, evidence, unresolved mentions, and bounded neighbors where the contract supports them. Unknown request members, unbounded traversal, and arbitrary SQL are rejected.
Give agents the same bounded reads
tools <- graft_tools(view)
names(tools)The definitions call graft_find(),
graft_get(), graft_query(), and
graft_history() through the captured view, so later commits
cannot change their results. They expose no write operation, raw
database connection, filesystem access, or network access. The host
decides which provider receives them and remains responsible for tool
authorization.
Every operation reports its applicable limits and truncation state so a host can distinguish a complete result from a bounded prefix.
graft_close(store)Read Change control for the path from proposal to accepted revision and Architecture for how the ledger and derived views fit together.