Repository navigation
upgrade repairs the installed-file record, legacy request.body migration hint, shared env/secrets (#1131, #1132, #1133) - #1134
Merged
Conversation
…change (#1131) The reported failure came from a 0.6.5 `urlcode upgrade` moving a site to 0.6.6: that release's upgrade wrote no addon-files.lock.json at all, so the 0.6.6 `extensions list --strict` found every add-on unrecorded. The current upgrade already records moved add-ons inside its rollback, but an up-to-date site returned early, so re-running upgrade could never repair that state. - upgrade on an up-to-date site records each installed catalog add-on that still matches the installed core's pin and has no entry; a package npm moved off its pin is left for list --strict to report. UpgradeResult gains `recorded`, printed by the CLI. - writeFilesLock writes a temporary file and renames it into place, and a failed write is a ConfigError naming the file, so a record is never torn. - extensions|artifacts add reports `recorded` and says "Recorded the installed files of <name>" instead of "nothing to do" when only the record changed. - Tests: upgrade then list --strict passes with tarball-installed add-ons; an up-to-date unrecorded site is repaired; a mispinned one is not recorded; a record that cannot be written fails upgrade and rolls everything back; add reports the record write and "nothing to do" only for a true no-op. - docs/EXTENSIONS.md, CLI help and llms-full.txt describe it. Refs #1131 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hape (#1132) Policy keys (required, maxBytes, contentTypes, format, schema) written directly under request.body in a route or a shared block, the shape #870 keyed by HTTP method, now fail with one legacy-request-body error before the schema runs, instead of a generic unknown-key error for the first one only. - The error is located at the first such place (file:line:column, pointer, key) and gives one instruction per route and shared block, each later one with its own line and column: the keys to move, the method keys to move them under, and a one-line before/after (key names only, never values). - A route with methods moves every key under each method that takes a body, and maxBytes alone under its GET/HEAD/DELETE. A route without methods answers GET and HEAD: maxBytes moves under both, and any other key gets the suggestion to declare methods: [POST]. A shared block uses the methods every route that uses it answers. - explainError (MCP explain_error) returns the error's own hint as its guidance, so the CLI, MCP validate and explain_error give the same text. - docs/HTTP.md gains "Moving from the route-wide body shape" with the before/after, which the hint links through docsUrl(). No alias and no rewriting. Refs #1132 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner decision 2026-10-01 reverses the declined #576. A top-level shared block may declare env and secrets with the route-level shapes. A route that names it with use inherits them, merged name by name; the route's own entry wins. use is a single name, so two blocks can never conflict. Bindings are resolved into each route at load time, before hashing, so projectSha256, urlcode permissions (requested grants per route), the operator policy's per-route grants and revision pin, explain and audit all see each route's effective bindings. A block grants nothing and nothing becomes project-wide; adding a route to a block changes its requested grants and the revision, so the old pin is refused. Adds examples/shared-bindings, schema $defs envBindings/secretBindings shared by routes and shared blocks, tests, and docs (specification, bindings guide, FUNCTION-SECURITY, SECURITY, RIM-CFG-002). Refs #1133, #576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measured on the merged branch (Node 26): 1120281 packed, 4396305 unpacked, 565 entries. Budgets: 1098 KiB packed, 4300 KiB unpacked, 570 entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ource The #1121 workspace-package fact listed every directory under packages/, so an older checkout keeping a removed package's untracked dist/ or node_modules/ (ui, admin, forms, ...) failed check:docs and agent-facts.test.ts. A directory now counts only when it holds a package.json or core's src/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Problem and change
#1131:
urlcode upgradeleavesaddon-files.lock.jsonunwritten, soextensions list --strictfailsupgradecould never repair the missing record.list --strictto report.UpgradeResult.recordedlists what was recorded, and the CLI prints it.writeFilesLockwrites a temporary file and renames it into place. A failure names the file and fails the upgrade; a moving upgrade rolls back everything.extensions add: it reports "Recorded the installed files of X…" when it only writes the record. "nothing to do" appears only for a true no-op.--jsoncarriesrecorded.#1132: targeted migration hint for the route-wide
request.bodyshape (#870)required,maxBytes,contentTypes,formatorschemadirectly underrequest.body, in a route or a shared block) is refused with one error, codelegacy-request-body, before the generic schema errors.docs/HTTP.md#moving-from-the-route-wide-body-shapethroughdocsUrl(). Extra places are listed with their line and column, capped at 8.validateandexplain_errorall give it.#1133:
shared:blocks may carryenvandsecrets(owner reversed #576)$defs/envBindingsand$defs/secretBindings, so shapes and limits are identical.usestays a single name, so two blocks never conflict.permissionslists the inherited grants under each route that uses the block, and only there.projectSha256, so an old policy is refused. A policy granting/astill refuses/b.explainshows binding names and never values.yaml/organization, FUNCTION-SECURITY, SECURITY.md (the reversed decision and how per-route visibility is kept) and the RIM-CFG-002 card. There is a newexamples/shared-bindingsexample.Also included: the #1121 agent-facts check now counts only
packages/directories that hold source. Before, an older checkout's leftoverdist/ornode_modules/from a removed package failedcheck:docs.Verification
npm run verifyexits 0 on this exact tree.npm run test:packageexits 0: "43 packaged example commands ran from consumer copies; Packed installation and starter/cookbook checks passed".New tests:
test/upgrade.test.ts: 4 new; three fail on main.test/addon-files.test.ts: record-only add output.test/legacy-request-body.test.ts: 5 tests, including the exact-message snapshot.test/shared-blocks.test.ts: 9 new.Core package budget, from the merged measurement:
Limitations
urlcode upgradeunder the next release, then a commit ofaddon-files.lock.json. This belongs in the release notes.addornpm ci.urlcode routesdoesn't list bindings for any route (existing behaviour).env; secret inheritance is covered by tests.MCP_ENABLED_SKILLSroutes that motivated this live in the private urlcode-ai project, not this repo, so they're a follow-up there after release.Closes #1131
Closes #1132
Closes #1133
🤖 Generated with Claude Code