in lua, require caches its argument, dofile doesn’t.
IOW, require 'foo' always does nothing if foo was already loaded using require. this is ususally desired behavior except during development when you’re changing module code.
a workaround during development is to clear the entry for foo in the cache:
package.loaded.foo = nil
if you want to always run foo.lua then use dofile('/path/to/foo.lua') (notice the full filename). rule of thumb: this is fine for “local” libraries (in your script’s directory) and require is probably better for core modules (from ~/norns/lua or equivalent - you shouldn’t be explicitly specifying paths for those since they may move around, and you shouldn’t be needing to edit them as a matter of course.)
in the specific case of softcut “child scripts” like halfsecond, i personally would advocate making “local” copies of those, customizing them for your needs, and running them with dofile from your “main script.”