Skip to content

Detect outdated skills, modify version command triggers - #92

Merged
brandonc merged 24 commits into
mainfrom
TF-39526-detect-skill-md-drift-and-prompt-users-to-re-install
Jul 29, 2026
Merged

Detect outdated skills, modify version command triggers#92
brandonc merged 24 commits into
mainfrom
TF-39526-detect-skill-md-drift-and-prompt-users-to-re-install

Conversation

@brandonc

@brandonc brandonc commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Description

A few different 0.4.0 cleanups:

  • tfctl, tfctl --version, tfctl -v, tfctl version all run the hidden version subcommand, which now does the checkpoint rendering.
  • main.go now does a sweep of installed SKILL.md files that may have been installed by previous versions and migrates them to the latest version if necessary.
  • SHA256 hashes for each releases' skill file are embedded in the binary using make prepare-release
  • main.go reorganized a bit for simplicity
  • harness exec no longer accepts values "all" and "reversible", making all resources explicit. I think this will be easier to understand.
  • harness install no longer requires auth setup first
  • Used the resource registry to determine destroyability for execsession instead of a separate list.
  • Expanded the resource registry to include a lot more resources.

Example Output

Screenshot 2026-07-26 at 09 49 19 Screenshot 2026-07-28 at 15 24 21

PR Checklist

  • Run npx changie new or install changie to prepare a new changelog entry for the next set of release notes.
  • Ensure any command changes are sensitive to these global flags:
    • --json — Force machine readable output to stdout. Does not apply to stderr.
    • --markdown — Force markdown output to stdout. Does not apply to stderr.
    • --dry-run — Don't make any actual writes or other mutations. Describe what would have changed to stderr.
    • --quiet — Only render essential content.
  • Get the logging interface from the context and add debug logging for interesting conditions and nonfatal situations.
  • Run make gen/screenshot if the root command output changes.
  • Add the Autocomplete field to positional arguments and flags to assist shell autocomplete.

PCI review checklist

  • I have documented a clear reason for, and description of, the change I am making.

  • If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.

  • If applicable, I've documented the impact of any changes to security controls.

    Examples of changes to security controls include using new access control methods, adding or removing logging pipelines, etc.

Comment thread skills/migrate.go Outdated
} else {
// This is not a match for any known skill and should not be migrated, but
// may be outdated.
migrationResult <- &MigrationResult{

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A user-customized skill is not a migration failure but the caller in main.go logs this as logger.Error("Failed to migrate skill", ...). Either we shouldn't emit a result here or add a field to distinguish skipping cuz its unknown" from actually failed to write, rn every user who edited their SKILL.md gets an error in --debug output

Comment thread skills/install.go Outdated
defer targetFile.Close()
defer file.Close()

tempFile, err := os.CreateTemp("", fmt.Sprintf("SKILL-%s-*", version.Name))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Empty string dir means os.TempDir() which is usually /tmp so if the target path is on a different filesystem, os.Rename fails on Linux. Could use os.CreateTemp(filepath.Dir(path), ...) instead

Also os.Rename is called while tempFile is still open. Can u rename an open file? I think on windows u cant, u may need tempFile.Close() before calling rename

Comment thread skills/install.go Outdated

found, ok := resource.ByName(grant)
if !ok {
warnings = append(warnings, fmt.Sprintf("unknown resource type %q in --allow-delete; it may still be honored", grant))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does AllowsDelete not automatically deny this at runtime for unknown types? I know we went over this in our call but it seems like the first loop only matches if the strings are equal which they wouldn't be right?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Which loop? I think the permissions for unknown types works because I smoke tested it:

Screenshot 2026-07-28 at 20 14 33

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

my bad, i misread

// The result must be sorted and free of duplicates for deterministic
// completion output.
assert.True(t, sort.StringsAreSorted(got), "completions must be sorted")
assert.True(t, slices.IsSorted(got), "completions must be sorted")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

shd we remove this assertion on sorting since the registry resources arent sorted anymore?

Comment thread Makefile Outdated
@if [ -z "$(VERSION)" ]; then echo "VERSION is not set"; exit 1; fi
@echo $(VERSION) > $(VERSION_FILE)
@echo "Updated $(VERSION_FILE) to $(VERSION)"
@echo "v$(VERSION) $$(sha256sum $(SKILL_EMBEDDED) | cut -d' ' -f1)" >> $(SKILL_HASHES)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

sha256sum doesn't exist on macOS does that matter?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good call out. I thought it was built in. I'll use shasum -a 256

@shwetamurali

Copy link
Copy Markdown
Collaborator

a few higher level comments:

  1. If a user upgrades tfctl, runs tfctl get workspaces, and their skill file changes they have no idea cuz success is only logged at Debug level. Would we wanna at minimum, print one line to stderr on success that tells them we migrated the skills? Also, do we really want to write to local files during a read only API call?
  2. Shd we do smth similar to HOMEBREW_NO_AUTO_UPDATE such as an env var TFCTL_SKIP_MIGRATE=1 to disable auto migration?
  3. If a user wants to know what the skill update actually changed there's no diff or link to release notes, should we point them somwhere? For example, "Migrated .bob/skills/tfctl/SKILL.md from v0.3.0. See https://github.com/hashicorp/tfctl-cli/blob/v0.4.0/CHANGELOG.md".

Comment thread skills/migrate.go Outdated
}

// WaitForMigration waits for the migration process to complete and returns all MigrationResults.
func WaitForMigration() []MigrationResult {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If installSkillToPath hangs the CLI hangs at exit with no timeout. The context passed to MigrateInstalled is the shutdown context, but nothing in the migration code checks ctx.Done(). Can we add a select with a deadline, or a hard timeout to aboid hanging indefinitely?

brandonc added 3 commits July 28, 2026 20:00
- allow context cancelation while migrating skills
- don't migrate when --dry-run is used
- allow --argument=true form of arguments when checking global args
- use `shasum -a 256` instead of `sha256sums` in Makefile because it's more portable
- remove some unneeded code
This fixes a corner case where the symlink could change after it's resolved but before the target was overwritten
@brandonc

Copy link
Copy Markdown
Collaborator Author

@shwetamurali I think I addressed all feedback. Thanks!

@brandonc brandonc mentioned this pull request Jul 29, 2026
8 tasks
@brandonc
brandonc merged commit c3b7c8f into main Jul 29, 2026
2 checks passed
@brandonc
brandonc deleted the TF-39526-detect-skill-md-drift-and-prompt-users-to-re-install branch July 29, 2026 17:57
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.

2 participants