Skip to content

Rerender single functionality#216

Draft
NejcS wants to merge 11 commits into
mainfrom
feat/single-functionality-rerender
Draft

Rerender single functionality#216
NejcS wants to merge 11 commits into
mainfrom
feat/single-functionality-rerender

Conversation

@NejcS

@NejcS NejcS commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

This adds a way to rerender a single functionality in a project that has been completely rendered before.

Usage: codeplain --rerender 2 project.plain

How it works:

  1. it checks if the project has been rendered and it removes the conformance tests for the functionality that is being rerendered (e.g.: FR 2 in a project with 4 FRs).
  2. it gets the old specs of FR 2 and it provides them to the render_functional_requirement call. It also instructs the model to do a rerender and that code related to old specs must be removed (see https://github.com/Codeplain-ai/plain2code_rest_api/pull/105)
  3. then it applies a commit with the implementation changes on top of the other commits (with a different commit message) and it also runs the conformance test for FR 2
  4. then it runs all of the other conformance tests (1, 3, 4)
  5. it also updates module_metadata.json with the new FR specs and hash

Example

Example run on a project with 4 FRs:

***functional specs***
- :User: should be able to add :Task:. Only valid :Task: items can be added.
- :User: should be able to delete :Task:
- :User: should be able to view :Task: name, notes, due date, and status by running the :App: with CLI argument --view <task_id>.
- Show :TaskList:

Then I changed number 3 to:

- :User: should be able to mark :Task: as completed.

and I ran it with --rerender 3.

This are the logs:
codeplain.log

The commits in the rendered module:

* c87ec04 (HEAD -> main) [Codeplain] functionality ID (FRID):3 fully reimplemented
* 11d5bca [Codeplain] Fixed issues in the implementation code identified during conformance testing
* 2a29914 [Codeplain] Implemented code and unit tests for functionality 3
* 5dc2e76 [Codeplain] functionality ID (FRID):4 fully implemented
* d0a4199 [Codeplain] Implemented code and unit tests for functionality 4
* 5f405ad [Codeplain] functionality ID (FRID):3 fully implemented
* 00960ac [Codeplain] Implemented code and unit tests for functionality 3
* a2fc0f7 [Codeplain] functionality ID (FRID):2 fully implemented
* dc2a6d2 [Codeplain] Fixed issues in the implementation code identified during conformance testing
* a1ca663 [Codeplain] Implemented code and unit tests for functionality 2
* c6b0c86 [Codeplain] functionality ID (FRID):1 fully implemented
* 42489c3 [Codeplain] Implemented code and unit tests for functionality 1
* 1ba6c4a [Codeplain] Initial module commit

Commits in the conformance_tests:

* e8f0ae8 (HEAD -> main) - :User: should be able to mark :Task: as completed.
* 85f7947 - Show :TaskList:
* 7ea42af - :User: should be able to view :Task: name, notes, due date, and status by running the :App: with CLI argument --view <task_id>.
* 7d2a1ee - :User: should be able to delete :Task:
* 889e153 - :User: should be able to add :Task:. Only valid :Task: items can be added.
* e28ad48 [Codeplain] Initial module commitq

The conformance tests:

conformance_tests.json
task_addition_validation
task_completion_verification
task_deletion_verification
task_list_display_verification

And the implementation code was changed too and the stuff related to the old spec was removed.

80cf5ee7-bcb5-4094-b293-e0d73a57f45c

Additional notes:

  • it shouldn't be a surprise but still worth noting that: running codeplain with --render-from N on a project that has had --rerender used on it will still make the tool render the range from N-1. The "reimplementation" commits will get discarded anyway.
  • this branch is based on the impr/state-machine-cleanup branch, I will rebase this once that's merged

@NejcS NejcS self-assigned this Jun 8, 2026

terminal_frid = (
list(plain_spec.get_frids(self.plain_source_tree))[-1] if self.is_rerender else ctx.frid_being_implemented
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this in order to run the whole collection of conformance tests.

e.g.: if you have a project with 4 FRs and you rerender FR 2 it will run the conformance tests like 2, 1, 3, 4. When not rerendering it still only runs the tests up to the one that is currently being implemented.

self._setup_test_specifications()
if not ctx.current_conformance_tests_exist():
return

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is here in order to skip the tests for FR 2 (if we take the example from the comment above). The conformance tests for FR 2 have already passed at this point.

),
f"{States.IMPLEMENTING_FRID.value}_{States.PROCESSING_CONFORMANCE_TESTS.value}_{States.POSTPROCESSING_CONFORMANCE_TESTS.value}_{States.CONFORMANCE_TESTS_READY_FOR_AMBIGUITY_ANALYSIS.value}": AnalyzeSpecificationAmbiguity(),
f"{States.IMPLEMENTING_FRID.value}_{States.FRID_FULLY_IMPLEMENTED.value}": FinishFunctionalRequirement(
git_utils.FUNCTIONAL_REQUIREMENT_FINISHED_COMMIT_MESSAGE

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed anymore since the action now constructs its own commit message (because it needs render_context.is_rerender to construct it)

Comment thread .gitignore
.coverage
logging_config.yaml

.claude/worktrees/ No newline at end of file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated change: was wokring in a worktree and this directory kept popping up in the changes and I think we should ignore it if you're using worktrees.

Comment thread plain_modules.py
os.makedirs(codeplain_folder, exist_ok=True)
with open(self.module_metadata_path(), "w", encoding="utf-8") as f:
json.dump(metadata, f, indent=4)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes the JSON's content to be out of order but I don't think that's important because JSON by standards doesn't need to have ordered keys.

e.g.: if you render a project with FRs 1, 2, 3 and then rerender 2, you would get the content of the module_metadata.json file as: { "1": {...}, "3": {...}, "2": {...},}

@NejcS NejcS marked this pull request as ready for review June 9, 2026 06:18
@NejcS NejcS requested a review from pedjaradenkovic June 9, 2026 06:18
@NejcS NejcS force-pushed the feat/single-functionality-rerender branch from 24d6304 to 820cc30 Compare June 9, 2026 13:06
@NejcS NejcS force-pushed the impr/state-machine-cleanup branch from 4d34831 to 81b94d5 Compare June 9, 2026 13:24
Base automatically changed from impr/state-machine-cleanup to main June 9, 2026 14:19
NejcS added 11 commits June 10, 2026 09:22
- New `--rerender N` CLI flag renders a single FRID on top of current HEAD
  without reverting the build repo, unlike `--render-range`/`--render-from`
- PrepareRepositories validates the target FRID and loads the old spec text
  from module_metadata.json so the LLM can produce a targeted patch
- Stale conformance tests for the FRID are deleted (uncommitted) before
  rendering so CommitConformanceTestsChanges picks them up naturally
- FinishFunctionalRequirement and CommitConformanceTestsChanges select
  FUNCTIONAL_REQUIREMENT_REIMPLEMENTED_COMMIT_MESSAGE at runtime via
  render_context.is_rerender, keeping --render-range revert logic intact
- get_last_rendered_functionality searches both "implemented" and
  "reimplemented" patterns and returns the more recent match
update_frid_in_module_metadata writes the spec text for the just-finished
FRID into .codeplain/module_metadata.json before the FRID checkpoint commit,
so every git commit in the build repo contains an up-to-date functionalities
array. This makes old spec text available to --rerender even after git clean.
For a rerender it updates the existing slot in-place rather than appending.
@NejcS NejcS force-pushed the feat/single-functionality-rerender branch from 820cc30 to a3d6131 Compare June 10, 2026 07:23
@NejcS NejcS marked this pull request as draft June 29, 2026 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant