feat(job-array-one-based-index): parse submit index expressions (task 6.1)

ParseSubmitIndexExpr accepts only name[1-N] and name[1] (leading zeros
allowed) and otherwise reports the lowest-numbered broken rule with its
specific message: interactive arrays (2.1), invalid name or malformed
expression (2.2), lists/steps (2.3), %N (2.4), start 0 (2.5), reversed
(2.6), start above 1 (2.7), above the limit (2.8). Oversized numbers
saturate for the bound checks while reversal compares the digit
strings, so the rule order holds for any input. Not yet wired into
CreateJob (task 6.2).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-10-01 11:47:23 +00:00
parent 3a7e3890e2
commit 0318ac5f44
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
3 changed files with 359 additions and 1 deletions

View file

@ -121,7 +121,7 @@
- _Depends: 5.1_
- [ ] 6. API server: array submission
- [ ] 6.1 (P) Parse submit index expressions
- [x] 6.1 (P) Parse submit index expressions
- Accept only `name[1-N]` and `name[1]`; reject interactive arrays, malformed expressions or invalid names (quoting the name), lists and steps, `%N`, start 0, reversed ranges, start above 1 and sizes above the limit, each with its specific message, reporting only the lowest-numbered broken rule
- Saturate oversized numbers so the rule order still decides; accept leading zeros
- Done when the index-expression unit tests pass for every rule, the precedence rows (`[0-0:2]`, `[99999999999999999999]`, `[99999999999999999999-5]`, `[0-99999999999999999999]`), leading zeros, `[1]` vs `[1-1]` vs `[5]` and the limit edge
@ -245,3 +245,4 @@
- 4.3: the controller acks `setpend` (`do_set_preason`, job.c ~3869-3880) and `jobrun` (`handle_jobdispatch`, job.c ~2246-2258) with status 0 before doing the work, so those two harness commands can never report not-found; 4.7/5.13 for them depend on a controller change outside this spec's boundary. `jobinfo`'s not-found is `rc == 0` with no row (`do_reply_joblist`), not -ENOENT.
- 5.1: Go helpers: `ParseHumanJobIDStrict(s) (uint64, error)` returns sentinel `ErrJobIDSyntax` / `ErrJobIDWidth` (callers trim and split `[...]` first; no whitespace accepted); `MakeElementID(key uint64, k int) uint64`; `IsArrayCapableKey(key)`; `GenerateArrayJobID(c, a, n)` (non-cgo stub returns errNoCGO).
- 5.4: handler fixture in `controllers/jobs_handler_test.go` (`newHandlerFixture`, `seedJob`/`seedOrdinaryJob`/`seedArrayElements`/`seedQueue`, `submit`, `controlByID`, `controlByFilter`, `dispatchedIDs`, `submissions`); submit bodies must be client-style JSON maps (marshalled `models.JobSubmitRequest` breaks on zero CustomTime). Handlers are registered without `RequirePermission`; in-handler RBAC/queue/status checks still run.
- 6.1: the design's "saturate oversized numbers" rule alone loses the order of two oversized numbers; `ParseSubmitIndexExpr` compares leading-zero-stripped digit strings for 2.6. Use the same approach for the selection parsers' reversed-range check (7.1, 8.1) if they saturate. Rule tags are strings "2.1".."2.8" on `*ArrayExprError`.