Parameter extraction: take: param in forge unify, ingredient param defaults - #14
Merged
Merged
Conversation
An ingredient may declare params with a scalar default, and a plan hunk may be take: param with its params; the engine refuses param until it can apply it.
…m layer An ingredient's declared defaults fill only its own placeholders, under every recipe, profile and workspace layer; a Forge without declarations renders exactly as before.
substitute used `key in params`, so {{constructor}} rendered as the native Object function.
Byte change: a body holding {{constructor}}, {{toString}} or {{__proto__}} now keeps it literal.
Parameter extraction replaces a region by position, so the word diff now carries each region's character span; classifyHunk's output does not change.
A take: param hunk turns each changed region into {{key}} by position, carries the base's
text as the default and the variant's as the value, pre-fills from the value suggestion,
and refuses anything the equivalence proof could not reproduce.
…xtraction The rows only the whole Forge can decide (the profile exists, no other profile uses the variant, no layer or ingredient already holds the key), then both YAML edits rendered in place, refused unless the file round-trips and reads back as exactly the new entries.
Declarations, template and profile values are written in an emission-neutral order after every gate passed; --json gains params and profileEdited, and two warnings name what unify cannot check from inside the Forge.
…tion import compares literal workspace text with the templated base and creates a variant; template-aware import is the next slice.
…profiles unchanged A golden Forge with two extractions (LF and CRLF + BOM) reproduces its expected tree, and two workspaces synced before, one per profile, stay unchanged byte for byte; a control without the profile values shows update.
The forge unify row, the ingredient params and their place in the layer order, and the 0.5.0 upgrade notes (older CLIs, re-import, the substitute fix); --help says the same.
P15 and P16 refused every reuse, because the first extraction's profile holds a value; for
a reused key the base already renders {{key}}, so no layer it sees moves. Profiles are found as
loadForge finds them: real directories only, never a symlinked one it would not read.
…params The --json contract of spec 09 section 4.5: written lists every base file this run wrote, and params is [] when every key was already declared and valued.
A copied regex would go stale silently if an emitter narrowed its set; the emitters now own them. Byte-neutral: the patterns are unchanged.
Reuse of an extracted key, P3, P7, P10 on metadata, P20, the alias refusal, ignored and untracked profiles, a late failure naming the profile, comments and BOM kept, and a mixed plan seen from a base workspace. The README forge unify row now says unify edits a profile.
A reused site merged first kept the key marked reused even when a later site put new text under it, so P15/P16 and W1 were skipped and another profile's text could change silently.
The text report now agrees with --json params, which lists only the keys this run wrote.
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
craftar@0.5.0to npm after approval in thenpmenvironment.forge unifyplan hunk may betake: param. Each listed token becomes{{key}}in the base, the base's text is declared as the key's default in itsingredient.yaml, and the variant's text goes into the variant profile'sprofile.yamlparams— only after an equivalence proof shows both sides render back exactly, and only when the same plan resolves the variant.--save-planpre-fillsparamsforvaluehunks.paramsdefaults are the weakest layer, scoped to that ingredient (paramsFor).substituteresolves own properties only —{{constructor}},{{toString}},{{__proto__}}no longer render built-in JavaScript members.Emitted bytes — which workspaces see a change
{{constructor}},{{toString}},{{__proto__}}(or anotherObject.prototypename) seesupdate: that placeholder now stays literal (commit8e259be, user-approved).params, soparamsForreturns exactly the old params map. Old goldens (forge-unify,acme-portal,acme-web) are unchanged.Upgrade note
README § Upgrading → to 0.5.0: a Forge edited with
take: paramneeds 0.5.0 in every workspace that syncs it (0.4.0 refuses ingredientparams);importis not template-aware yet (re-importing over an extracted base creates a variant and drops the profile's params —unifywarns, W2); thesubstitutefix above.Test plan
npm run typecheck— passesnpm run build— passesnpx vitest run --exclude test/ci.test.ts(Linux) — 445 passed / 5 skippedtest/golden/forge-param(LF, and CRLF + BOM) reproduces its expected tree; a fresh--save-planreproduces the committed plansacmeandglobexworkspaces synced before, every fileunchangedbyte for byte after both extractions across claude-code, kiro and agents-md; negative control without the profile values showsupdateskipIf(win32 || root))node-cli-revieweranddocs-author: clean after two correction rounds (reuse case refused by P16, mixed reused+literal key skipping P15/P16,--json written/params, profile lookup by real directory, emitter regexes shared, missing refusal tests)— already in placetext marker has no test of its own