Regeneration & Synchronization¶
At the heart of GTB's Manifest-Driven Development are the Regeneration Commands. These commands enable a bi-directional synchronization between your high-level design (manifest.yaml) and your actual Go implementation.
The Bi-Directional Loop¶
GTB does not lock you into a single way of working. It supports two primary synchronization directions:
1. Manifest -> Code (regenerate project)¶
This is the Design-First workflow.
- Action: You update the
.gtb/manifest.yamlfile (e.g., renaming a command, adding flags, or moving a subcommand). - Result: Running
regenerate projectrebuilds the wiring files (cmd.go,init.goif present) to match the new manifest structure. - Safety:
- It never overwrites your custom logic in
main.go(which is excluded from hashing and generation if it exists). - It protects manual changes in
init.goandcmd.goby verifying their content hashes against the manifest before regeneration. - Child command registrations are preserved. When a parent
cmd.gois overwritten, the pipeline's re-registration step reads the manifest to find all existing children and re-injects theirAddCommandcalls. You will not lose child registrations across a regeneration. - Project-level settings (including help channel configuration) are fully preserved. The root
cmd.gois rebuilt viabuildSkeletonRootData, which maps all manifest fields — including Slack/Teams help-channel settings — into the rendered file. No settings are silently dropped.
- It never overwrites your custom logic in
2. Code -> Manifest (regenerate manifest)¶
This is the Code-First workflow.
- Action: You make structural changes directly in your Go source code (e.g., using a traditional Cobra implementation style).
- Result: Running
regenerate manifestuses AST (Abstract Syntax Tree) scanning to inspect your code and rebuild themanifest.yamlto reflect the current state of your binary.
Structural Expectations
The regenerate manifest command relies on the Standard Project Structure. If your codebase has been manually modified to depart significantly from this structure (e.g., non-standard package naming or manual Cobra registration bypasses), the scanner may fail to correctly identify commands or their properties.
The manifest is recoverable, not precious¶
The headline guarantee of the code-first path is that .gtb/manifest.yaml is
disposable. Delete the entire .gtb/ directory and run regenerate manifest,
and the generator rebuilds the full property set byte-for-byte from what is
already committed in your source tree — you are not left with a lossy skeleton.
Treat the manifest as a cache of the source, not as an irreplaceable original.
When no manifest is present, applyRecoveredProperties takes the from-scratch
path and reconstructs every property from three in-tree artefacts
(recoverNonLiteralProperties):
- The root
cmd.goToolliteral (AST scan) — name, description, release source, env prefix, update policy/interval, help channel, telemetry, and the feature set. Features are recovered from theprops.SetFeatures(...)call via the sharedtemplates.FeatureCatalogue, so every built-in toggle round-trips. cmd/<name>/keychain.go— the scaffold-onlykeychainfeature has noFeatureIDand never appears in theSetFeaturesliteral, so its state is recovered from the presence of this blank-import file.pkg/cmd/root/provenance.go— the signing posture, custom template-overlay pins, andmodule_published, which are recorded nowhere else in generated source (see The Manifest). The docs layout and any non-default CI component source are likewise re-derived from the docs tree and.gitlab-ci.yml.
The from-scratch reconstruction produces the same normalised, canonically-sorted
bytes that generate would have written, which is exactly what makes the
Cyclical Sync below a meaningful test.
When a manifest already exists
When .gtb/manifest.yaml is present, regenerate manifest treats it as
authoritative for author-set fields and refreshes only the source-of-truth
fields (name, description, release source) from cmd.go — it does not
re-derive features and other posture from source on this path. The
byte-exact full reconstruction described above is the from-scratch
(manifest-absent) behaviour.
Why is Regeneration Valuable?¶
Architectural Integrity¶
In large CLI tools, it's easy for the command hierarchy to become inconsistent. Regeneration ensures that the "intended" design (in the manifest) and the "actual" design (in the code) stay perfectly in sync.
Rapid Refactoring¶
Renaming a root command or moving 10 subcommands to a different parent is traditionally a painful manual process of renaming packages and updating imports. With GTB, you simply edit the manifest and run one command to refactor your entire project structure.
Manual Cleanup Required
While regeneration creates the new command structure for you, it currently does not automatically:
- Remove Old Files: Stale packages or commands from the previous design must be deleted manually.
- Migrate Logic: Any custom business logic in a command's
main.gofile must be moved to the new location by the developer.
We hope to implement this functoinality in future versions of the tool
Cyclical Validation (The "Ultimate Test")¶
Regeneration provides a robust mechanism for validating the framework itself. By running a "Cyclical Sync":
- Generate Code A from Manifest A.
- Generate Manifest B from Code A.
- If Manifest A and Manifest B are identical, you have absolute proof that the generator and scanner are perfectly consistent.
The Verification Loop
This cyclical sync is used internally by GTB to ensure that the code we generate today will always be correctly understood and manageable by the framework tomorrow.
Summary¶
Regeneration transforms the manifest.yaml from a static configuration file into a Living Design Document. It gives you the freedom to evolve your tool's interface without the overhead of manual boilerplate management, while providing a mathematically verifiable guarantee of architectural consistency.