The project-rollup forms derive originator from the selected Package
(party folder) server-side, so the field is read-only and was blank
until submit. Add a declarative `ui:mirrorFrom: <sibling>` hint: the
object renderer wires the named sibling's input to the field so the
read-only originator updates live as the user picks a party — the
composing tracking number is visible while filling the form. Display
only; the server stays authoritative via the cascade's folder_fields.
Set `ui:mirrorFrom: party` on originator in the embedded
default-project-{mdl,rsk}.form.yaml. Generic hint, not hardcoded field
names, so operators can reuse it.
Test: form-safety.spec.js — filling the source field updates the
read-only target; the target is not editable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two coupled cleanups so the baked-in defaults reflect the actual
convention instead of leaking one project's choices into every
deployment:
- Drop the project-wide phase/area components from the default
filename_format, form schemas, and table columns. They must be
all-on or all-off across a project to keep filenames lexically
consistent, so the simplest default omits them; operators re-enable
via the commented-out templates + a .zddc filename_format override.
Teaching comments (incl. a field_codes: example) now ride along in
defaults.zddc.yaml, which `show-defaults` dumps verbatim.
- Separate suffix from sequence with a template hyphen
({sequence}-{suffix?}); stored suffix is now just the part marker
(A, 01) with no leading dash.
- New records: key `folder_fields: {field: parent-distance}` binds a
body field to an ancestor folder name. The default mdl/rsk records
bind originator to the party folder (distance 1) — the folder is the
sole source of truth. The server overwrites the body value before
validation + composition (WriteWithHistory and the rollup create
path), and the form renderer marks the field read-only and pre-fills
it. Rollup forms drop originator from required (server derives it
from the selected party).
Tests: folder-binding overwrite + wrong-originator-filename 422, and a
form-render readOnly/prefill assertion; existing record tests realigned
so the party folder name equals the originator.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds history_test.go with eight cases exercising the record-write
orchestration path:
- CreateStampsAuditFields: PUT to a fresh mdl path → audit fields
injected; response echoes the stamped YAML; no history dir yet.
- UpdateIncrementsRevisionAndArchivesPrior: second PUT archives
the prior bytes under .history/<base>/<ts>-<sha8>.yaml, bumps
revision, preserves created_*, chains previous_sha.
- ConflictPreservesHistory: 412 from stale If-Match leaves the live
file untouched and writes NO history entry (the failed write must
be a true no-op).
- ClientAuditFieldsStripped: client-supplied created_by / revision
are silently overwritten by server values — anti-forgery test.
- FilenameMismatch: URL says ...-0002 but body composes to ...-0001
→ 422.
- LockedFieldRejected: posting type=SPC to an rsk row → 422 with
/type error (rsk/ locks type=RSK via cascade).
- SSRHistoryAtPartyLevel: writes to archive/<party>/ssr.yaml put
history at archive/<party>/.history/ssr/, NOT at
archive/.history/<party>/.
- RollupCreate_AssignsRowAndComposesFilename: three POSTs to
/project/rsk/form.html in two table-scope groups demonstrate the
server picks up filename_format + row_field+row_scope_fields from
the cascade, auto-assigns sequence row numbers per group, and
composes the canonical filename.
Bug fix surfaced by the first test: composeFilename was eliding TWO
separators around an optional placeholder when one was correct.
"ACM-{phase?}-PRJ" with phase="" was producing "ACMPRJ" instead of
"ACM-PRJ". Now drops only the trailing separator from output and
lets the next iteration emit the connector.
Default-project-{mdl,rsk}.form.yaml updated: project-rollup MDL +
RSK schemas gained the six readOnly audit fields and the project-
rsk schema picked up the full table-tracking component shape (+
row) plus an enum-locked type=RSK. The required: list no longer
includes type for rsk schemas — the cascade's field_defaults
injects it after schema validation, and requiring it would 422
well-behaved clients.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The project-level MDL/RSK rollup specs lose `addable: false` and gain
a sibling form schema (default-project-{mdl,rsk}.form.yaml) that
makes `party` a required field. + Add row on the rollup view is now
live: the user types the party name in the Package column, the
server reads `party` from the body, validates that
<project>/archive/<party>/ exists on disk, strips the field, and
writes the row into archive/<party>/<slot>/<date>-<email>.yaml. The
response Location is the synthetic <project>/<slot>/<party>__<file>.yaml
URL so the rollup table client swaps the draft URL cleanly.
Wrong party = 422 with a clear error pointing at the SSR view as the
place to create the folder first. No auto-creation here — the rollup
is for filing deliverables/risks against existing packages, not for
spinning up new ones.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>