Skip to content

Commit 597985d

Browse files
tthayerclaude
andcommitted
fix(pkl): register call nodes in the ledgers and bind Pkl declarations
Merging main brought in three contracts this branch violated. repro_call_node_manifest requires a table row for every live call_node_types entry, so Pkl's unqualifiedAccessExpr/qualifiedAccessExpr (direct) and newExpr (constructor) each get one, with the partition totals moved to match. The historical-snapshot column is the audited ledger, not an archaeology record -- the suite hard-fails on a row that claims it was absent -- so a newly registered kind joins the snapshot with the change that registers it. repro_language_registry then requires every call-capable language to own exactly one call-argument matrix row, which turned out to be a real extractor gap rather than a bookkeeping entry. Pkl's grammar labels no production with a `name` field, so the generic declared-container rule never recognised a Pkl binding: method names, parameter names, and property names were each re-emitted as an ordinary read of themselves, which Go and Nickel do not do. Add a Pkl occurrence policy that binds the declared identifier of methodHeader, typedIdentifier, classProperty, objectProperty, clazz, and typeAlias, resolved against the nearest such container so annotations, defaults, and bodies stay reads. Recording the binding also supplies the lexical-shadow proof the matrix row asserts. Separately, a700bff gave the Windows helpers their own timeout floor but left the harness contract allowing the scheduler only eight seconds to finish refusing -- a path that can spend that floor twice, once proving descendants and once in the cleanup re-entry. The Windows shard died on subprocess.TimeoutExpired, taking shard-completeness with it. Derive the budget from the scheduler's own constant instead of restating it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Tony Thayer-Osborne <tony.thayerosborne@conductorone.com>
1 parent 9c25f16 commit 597985d

4 files changed

Lines changed: 61 additions & 14 deletions

File tree

‎internal/cbm/extract_usages.c‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ typedef enum {
374374
CBM_OCCURRENCE_VHDL_INTERFACE,
375375
CBM_OCCURRENCE_PINE_FUNCTION,
376376
CBM_OCCURRENCE_LLVM_FUNCTION,
377+
CBM_OCCURRENCE_PKL_DECLARATION,
377378
} CBMOccurrencePolicy;
378379

379380
typedef struct {
@@ -492,6 +493,7 @@ static const CBMOccurrenceSpec occurrence_specs[CBM_LANG_COUNT] = {
492493
[CBM_LANG_PINE] = {NULL, NULL, CBM_OCCURRENCE_PINE_FUNCTION, false},
493494
[CBM_LANG_PUPPET] = {NULL, NULL, CBM_OCCURRENCE_STANDARD, true},
494495
[CBM_LANG_LLVM_IR] = {llvm_binding_nodes, NULL, CBM_OCCURRENCE_LLVM_FUNCTION, false},
496+
[CBM_LANG_PKL] = {NULL, NULL, CBM_OCCURRENCE_PKL_DECLARATION, false},
495497
[CBM_LANG_MESON] = {NULL, meson_write_nodes, CBM_OCCURRENCE_STANDARD, true},
496498
[CBM_LANG_GN] = {NULL, gn_write_nodes, CBM_OCCURRENCE_STANDARD, true},
497499
[CBM_LANG_LINKERSCRIPT] = {NULL, linkerscript_write_nodes, CBM_OCCURRENCE_STANDARD, true},
@@ -985,6 +987,30 @@ static bool is_pine_function_binding(TSNode node) {
985987
return ancestor_field_binds(node, "function_declaration_statement", fields);
986988
}
987989

990+
/* Pkl declares names positionally: no production labels the declared identifier
991+
* with a `name` field, so the generic declared-container rule never binds them
992+
* and every method name, parameter name, and property name would be re-emitted
993+
* as an ordinary read of itself. Each container below holds its declared name
994+
* as named child 0; annotations, defaults, and bodies follow it and stay reads.
995+
* Resolve against the NEAREST container so a nested declaration's own name is
996+
* the only occurrence its parent can bind. */
997+
static bool is_pkl_declaration_binding(TSNode node) {
998+
static const char *const declaration_kinds[] = {"methodHeader",
999+
"typedIdentifier",
1000+
"classProperty",
1001+
"objectProperty",
1002+
"clazz",
1003+
"typeAlias",
1004+
NULL};
1005+
for (TSNode parent = ts_node_parent(node); !ts_node_is_null(parent);
1006+
parent = ts_node_parent(parent)) {
1007+
if (kind_in_exact_set(ts_node_type(parent), declaration_kinds)) {
1008+
return named_child_contains(parent, 0, node);
1009+
}
1010+
}
1011+
return false;
1012+
}
1013+
9881014
static bool is_policy_binding(CBMExtractCtx *ctx, TSNode node,
9891015
const CBMOccurrenceSpec *occurrence) {
9901016
switch (occurrence->policy) {
@@ -1041,6 +1067,8 @@ static bool is_policy_binding(CBMExtractCtx *ctx, TSNode node,
10411067
return is_vhdl_interface_binding(node);
10421068
case CBM_OCCURRENCE_PINE_FUNCTION:
10431069
return is_pine_function_binding(node);
1070+
case CBM_OCCURRENCE_PKL_DECLARATION:
1071+
return is_pkl_declaration_binding(node);
10441072
case CBM_OCCURRENCE_LLVM_FUNCTION:
10451073
for (TSNode parent = ts_node_parent(node); !ts_node_is_null(parent);
10461074
parent = ts_node_parent(parent)) {

‎tests/repro/repro_call_argument_matrix_b.c‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,12 @@ static const char TLAPLUS_BOUNDED_QUANTIFICATION[] =
752752
"Guard(values) == \\A item \\in values : item = item\n"
753753
"====\n";
754754

755+
/* Pkl access expressions double as plain property reads, so the bare fixture
756+
* also proves the un-applied reference is not promoted to a call. */
757+
static const char PKL_INSIDE[] = "function accept(value: Int): Int = value\n"
758+
"function run(watched: Int): Int = accept(watched)\n";
759+
static const char PKL_BARE[] = "function run(watched: Int): Int = watched\n";
760+
755761
static const char APEX_INSIDE[] = "public class Sample {\n"
756762
" private static Integer accept(Integer value) {\n"
757763
" return value;\n"
@@ -958,6 +964,9 @@ static const RoutineArgumentCase LLVM_IR_CASE = ROUTINE_ARGUMENT_CASE(
958964
static const RoutineArgumentCase TLAPLUS_CASE = ROUTINE_ARGUMENT_CASE(
959965
"TLAPLUS", CBM_LANG_TLAPLUS, "Sample.tla", TLAPLUS_INSIDE, TLAPLUS_BARE, "bound_op", "Guard",
960966
"Accept", "values", 1, 1, 0, "TLA+ operator application with a value argument");
967+
static const RoutineArgumentCase PKL_CASE = ROUTINE_ARGUMENT_CASE(
968+
"PKL", CBM_LANG_PKL, "sample.pkl", PKL_INSIDE, PKL_BARE, "unqualifiedAccessExpr", "run",
969+
"accept", "watched", 1, 1, 0, "native Pkl method application and property-read vocabulary");
961970
static const RoutineArgumentCase APEX_CASE = ROUTINE_ARGUMENT_CASE(
962971
"APEX", CBM_LANG_APEX, "Sample.cls", APEX_INSIDE, APEX_BARE, "method_invocation", "run",
963972
"accept", "watched", 1, 1, 0, "native method application");
@@ -1166,6 +1175,7 @@ DEFINE_ROUTINE_ARGUMENT_TEST(func, FUNC_CASE)
11661175
DEFINE_ROUTINE_ARGUMENT_TEST(puppet, PUPPET_CASE)
11671176
DEFINE_ROUTINE_ARGUMENT_TEST(slang, SLANG_CASE)
11681177
DEFINE_ROUTINE_ARGUMENT_TEST(llvm_ir, LLVM_IR_CASE)
1178+
DEFINE_ROUTINE_ARGUMENT_TEST(pkl, PKL_CASE)
11691179
DEFINE_ROUTINE_ARGUMENT_TEST(apex, APEX_CASE)
11701180
DEFINE_ROUTINE_ARGUMENT_TEST(pine, PINE_CASE)
11711181
DEFINE_ROUTINE_ARGUMENT_TEST(qml, QML_CASE)
@@ -1243,15 +1253,15 @@ TEST(repro_call_argument_matrix_b_domain_bitbake) {
12431253
}
12441254

12451255
enum {
1246-
ROUTINE_ARGUMENT_LANGUAGE_COUNT = 36,
1256+
ROUTINE_ARGUMENT_LANGUAGE_COUNT = 37,
12471257
MODULE_ARGUMENT_LANGUAGE_COUNT = 4,
12481258
DOMAIN_CONTROL_LANGUAGE_COUNT = 6,
12491259
MATRIX_LANGUAGE_COUNT = ROUTINE_ARGUMENT_LANGUAGE_COUNT + MODULE_ARGUMENT_LANGUAGE_COUNT +
12501260
DOMAIN_CONTROL_LANGUAGE_COUNT,
12511261
};
12521262

1253-
_Static_assert(MATRIX_LANGUAGE_COUNT == 46,
1254-
"RACKET..OBJECTSCRIPT_ROUTINE call-capable matrix must contain exactly 46 "
1263+
_Static_assert(MATRIX_LANGUAGE_COUNT == 47,
1264+
"RACKET..OBJECTSCRIPT_ROUTINE call-capable matrix must contain exactly 47 "
12551265
"language rows");
12561266

12571267
#define MATRIX_B_LANGUAGE_ROWS(X) \
@@ -1283,6 +1293,7 @@ _Static_assert(MATRIX_LANGUAGE_COUNT == 46,
12831293
X(repro_call_argument_matrix_b_routine_slang, SLANG_CASE.identity.language) \
12841294
X(repro_call_argument_matrix_b_routine_llvm_ir, LLVM_IR_CASE.identity.language) \
12851295
X(repro_call_argument_matrix_b_routine_tlaplus, TLAPLUS_CASE.identity.language) \
1296+
X(repro_call_argument_matrix_b_routine_pkl, PKL_CASE.identity.language) \
12861297
X(repro_call_argument_matrix_b_routine_apex, APEX_CASE.identity.language) \
12871298
X(repro_call_argument_matrix_b_routine_pine, PINE_CASE.identity.language) \
12881299
X(repro_call_argument_matrix_b_routine_qml, QML_CASE.identity.language) \

‎tests/repro/repro_call_node_manifest.c‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
* TLA+ bound_op is historical direct-call metadata. Bounded quantification is
1717
* not a historical ledger row; repro_call_argument_matrix_b is its separate
1818
* negative behavior guard.
19+
*
20+
* The historical-snapshot column is the audited ledger, not an archaeology
21+
* record: every registered call node owns a row, so a newly registered kind
22+
* (Pkl's access/new expressions) joins the snapshot with the change that
23+
* registers it.
1924
*/
2025
#include "test_framework.h"
2126
#include "lang_specs.h"
@@ -54,18 +59,18 @@ typedef struct {
5459
} CallNodeManifestEntry;
5560

5661
enum {
57-
EXPECTED_HISTORICAL_CALL_NODE_TOTAL = 219,
58-
EXPECTED_ACTIVE_PRIMARY_TOTAL = 189,
59-
EXPECTED_DIRECT_CALLS = 155,
60-
EXPECTED_CONSTRUCTOR_CALLS = 20,
62+
EXPECTED_HISTORICAL_CALL_NODE_TOTAL = 222,
63+
EXPECTED_ACTIVE_PRIMARY_TOTAL = 192,
64+
EXPECTED_DIRECT_CALLS = 157,
65+
EXPECTED_CONSTRUCTOR_CALLS = 21,
6166
EXPECTED_OPERATOR_CALLS = 12,
6267
EXPECTED_IMPLICIT_CALLS = 2,
6368
EXPECTED_DSL_INVOCATIONS = 14,
6469
EXPECTED_BUILD_DEPENDENCIES = 1,
6570
EXPECTED_CALLEE_WRAPPERS = 8,
6671
EXPECTED_ARGUMENT_WRAPPERS = 1,
6772
EXPECTED_CONTROL_OR_DOCUMENT_NONCALLS = 6,
68-
EXPECTED_PRIMARY_OWNERS = 189,
73+
EXPECTED_PRIMARY_OWNERS = 192,
6974
EXPECTED_SYNTHETIC_OWNERS = 10,
7075
EXPECTED_NO_CALL_EDGE_OWNERS = 20,
7176
EXPECTED_PRIMARY_OPERATOR_CALLS = 4,
@@ -296,6 +301,9 @@ static const CallNodeManifestEntry CALL_NODE_MANIFEST[] = {
296301
ENTRY(CBM_LANG_TLAPLUS, "function_evaluation", DIRECT_CALL, PRIMARY_EXTRACTOR, true, true),
297302
ENTRY(CBM_LANG_TLAPLUS, "call", DIRECT_CALL, PRIMARY_EXTRACTOR, true, true),
298303
ENTRY(CBM_LANG_TLAPLUS, "bound_op", DIRECT_CALL, PRIMARY_EXTRACTOR, true, true),
304+
ENTRY(CBM_LANG_PKL, "unqualifiedAccessExpr", DIRECT_CALL, PRIMARY_EXTRACTOR, true, true),
305+
ENTRY(CBM_LANG_PKL, "qualifiedAccessExpr", DIRECT_CALL, PRIMARY_EXTRACTOR, true, true),
306+
ENTRY(CBM_LANG_PKL, "newExpr", CONSTRUCTOR_CALL, PRIMARY_EXTRACTOR, true, true),
299307
ENTRY(CBM_LANG_APEX, "method_invocation", DIRECT_CALL, PRIMARY_EXTRACTOR, true, true),
300308
ENTRY(CBM_LANG_PINE, "call", DIRECT_CALL, PRIMARY_EXTRACTOR, true, true),
301309
ENTRY(CBM_LANG_MOJO, "call", DIRECT_CALL, PRIMARY_EXTRACTOR, true, true),

‎tests/repro/repro_language_registry.c‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ static const LanguageCapabilityEntry LANGUAGE_CAPABILITIES[CBM_LANG_COUNT] = {
195195
NO_CALL(SMITHY),
196196
NO_CALL(WIT),
197197
CALL_WITH_REFERENCE_VOCAB(TLAPLUS),
198-
NO_CALL(PKL),
198+
CALL_WITH_REFERENCE_VOCAB(PKL),
199199
NO_CALL(GOMOD),
200200
CALL_WITH_REFERENCE_VOCAB(APEX),
201201
NO_CALL(SOQL),
@@ -298,8 +298,8 @@ TEST(repro_language_capability_ledger_covers_every_enum) {
298298
}
299299
}
300300

301-
if (counts[CAP_CALL_WITH_REFERENCE_VOCAB] != 86 ||
302-
counts[CAP_CALL_WITHOUT_REFERENCE_VOCAB] != 25 || counts[CAP_NO_CALL] != 50 ||
301+
if (counts[CAP_CALL_WITH_REFERENCE_VOCAB] != 87 ||
302+
counts[CAP_CALL_WITHOUT_REFERENCE_VOCAB] != 25 || counts[CAP_NO_CALL] != 49 ||
303303
counts[CAP_TRANSFORM_ONLY] != 1 || counts[CAP_UNSUPPORTED] != 1) {
304304
fprintf(stderr,
305305
" [language-registry] invariant=capability_partition call_ref_vocab=%d ref_gap=%d "
@@ -316,9 +316,9 @@ TEST(repro_language_capability_ledger_covers_every_enum) {
316316
TEST(repro_call_argument_matrices_equal_call_capability_ledger) {
317317
enum {
318318
EXPECTED_MATRIX_A_ROWS = 67,
319-
EXPECTED_MATRIX_B_ROWS = 46,
320-
EXPECTED_CALL_CAPABLE_LANGUAGES = 111,
321-
EXPECTED_NON_CALL_LANGUAGES = 52,
319+
EXPECTED_MATRIX_B_ROWS = 47,
320+
EXPECTED_CALL_CAPABLE_LANGUAGES = 112,
321+
EXPECTED_NON_CALL_LANGUAGES = 51,
322322
EXPECTED_NON_CALL_DOMAIN_CONTROLS = 2,
323323
};
324324
CBMLanguage matrix_a_ids[CBM_LANG_COUNT];

0 commit comments

Comments
 (0)