Support bare :manifest() + chained field accessor for FILES - #272
Merged
Merged
Conversation
…ILES
$acme.files.:manifest():uuid() and $*.files.:manifest():uuid() now work,
literal-root and '*' alike -- driven by David's own worked examples
("get uuids from all registrations," "get all acme registration uuids").
Bare :manifest() means "every entry in the manifest" (Rule 1a/1b's own
territory), not one selected entity, so chaining a field accessor onto
it maps that field over every entry rather than reading it off a single
already-picked one. That's different in kind from the existing
:first():fingerprint()-style position (pointer + field accessor, no dot,
order-independent), which only ever reads a field off exactly one
selected entity -- confirmed via code tracing that neither dot placement
nor argument order was the actual blocker; the real gap was that no code
path mapped a field over many entities at once.
query() now recognizes this shape (a new
FilesReferenceFinder3._bare_manifest_field_call() helper, shared by
query(), _query_star_traversal(), and _extract_data()) and produces one
ReferenceResult3 per manifest entry -- the named-file's own manifest.json
for a literal root, the global arrivals ledger for '*'. No changes were
needed in resolve()/resolve_from(): their existing per-result
_extract_data() loop already turns N results into N resolved values for
free.
The pre-existing :name(...)+pointer, then :uuid() in name_three pattern
(narrow to one version, then read its field) is untouched and stays
equally valid, per David's own confirmation -- covered by a dedicated
test.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013gPjejPWvbWtjz2dw9h14M
6 tasks
dk107dk
pushed a commit
that referenced
this pull request
Aug 29, 2026
David's own worked examples, now confirmed working end-to-end (#272, #273): getting uuids from all/one named-file's registrations, and combining them with SUBTRACT/INTERSECT against a RESULTS-side reference. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013gPjejPWvbWtjz2dw9h14M
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
$acme.files.:manifest():uuid()and$*.files.:manifest():uuid()nowwork, literal-root and
'*'alike -- driven directly by David's ownworked examples ("get uuids from all registrations," "get all acme
registration uuids"), meant to combine with
SUBTRACT/INTERSECTagainst another reference expression.
Background
Neither form worked before this PR. The first framing of the gap was
"does this need a
.before the field accessor" -- traced live (parsingboth forms) and by code-reading before answering, since that turned out
to be the wrong axis.
:first():fingerprint()(pointer + field accessor,no dot, order-independent) already works today, but only because it
reads a field off exactly ONE already-selected entity. Bare
:manifest()does not select one entity -- it means "every entry in the manifest"
(Rule 1a/1b's own territory). Chaining a field accessor onto THAT asks
for something no code path did before: mapping a field over MANY entities
at once, regardless of dot placement.
Reference3.resolve_kindalready classified this shape correctly asMETADATA_FIELD(confirmed live viaterminal_functions), so the actualgap was narrower than it first looked:
query()needed to produce Nresults instead of raising, and
_extract_data()needed to read a fieldper result instead of assuming exactly one.
What changed
FilesReferenceFinder3._bare_manifest_field_call(name_one)-- newshared recognition helper: "name_one's path is a single, argument-less
:manifest()call, with exactly one chained field-accessor function."Reused identically by
query(),_query_star_traversal(), and_extract_data().query()(literal root): new branch reading the named-file's ownget_manifest(), oneReferenceResult3per entry._query_star_traversal(): new branch readingfiles_root_manifest(the global arrivals ledger, Rule 1a's ownresource) -- confirmed its entries use different key names than
per-name manifest entries (
"file_path"/"named_file_name", not"file") by readingFilesListener._prep_update()directly, ratherthan assuming the two manifests share a shape. Composes with
:regex()-at-root_major._extract_data(): widened theMETADATA_FIELDfield-lookup to alsotry the new helper, and to read from
files_root_manifestinstead ofget_manifest(root_major)whenroot_majoris the'*'token (not areal name).
resolve()/resolve_from(): no changes needed -- confirmed byreading them first that the existing per-result
_extract_data()loopalready turns N results into N resolved values for free.
The pre-existing
:name(...)+pointer, then:uuid()inname_threepattern (narrow to one version, then read its field) is untouched and
stays equally valid -- David's own explicit confirmation, covered by a
dedicated test.
Deliberately not built:
:all()/:flatten()/:groups()combined with achained field accessor -- partitioning semantics differ per marker, a
distinct question left on the bucket list.
Test plan
TestBareManifestFieldAccessor(8 cases, literal root): one resultper entry, resolved values (not whole entries), David's own exact
syntax, a second field (
:time()) to prove genericity, name_threerejection, more-than-one-chained-function rejection, non-field-
accessor rejection, pre-existing name_three pattern unaffected.
TestStarBareManifestFieldAccessor(4 cases,'*'root): sameshape against a dedicated ledger fixture with the real
"file_path"/"named_file_name"keys,:regex()composition,name_three rejection.
tests/references/full tree: 1555 passed.times (identical) -- the known, unrelated SFTP/S3 failures
requiring unset env vars (issue test_nos_server_config_1 crashes with a raw ValueError when SFTP_* env vars are unset, instead of failing clearly #216).
https://claude.ai/code/session_013gPjejPWvbWtjz2dw9h14M