QuickFlow 1.0.0
Techlosoft Automation Desk - Team variant
===============================================================================
WHAT IT IS
QuickFlow turns a workflow into a reusable, parameterised, auditable unit.
A workflow is a JSON file in a shared library directory. It declares its inputs
(name, type, whether it is required, a default, and for enums the allowed
values) and the ordered list of commands that make it up. A colleague who has
never read the file can run it correctly: `describe` tells them exactly what it
needs, QuickFlow validates what they supply before anything executes, and every
executed run is appended to a run ledger for audit.
This is the "shared library" member of the Automation Desk line. Its siblings
each run one fixed thing on demand or on a trigger; QuickFlow's subject is the
library itself - parameter declarations, validation, and the run record.
-------------------------------------------------------------------------------
COMMANDS
quickflow list --library
[--json]
Every workflow in the library, with its declared parameters, their types,
whether they are required, and their defaults.
quickflow describe --library [--json]
Full detail for one workflow: each parameter (name, type, required,
default, allowed values, description) and each step's exact argv.
quickflow run --library [--set key=value ...] [--apply]
[--ledger ] [--json]
Validate the supplied parameters against the declaration, substitute them
into every step, then execute the steps in order.
DRY RUN BY DEFAULT. Without --apply it prints the fully substituted
commands that would run and executes nothing.
quickflow validate --library [--json]
Check every workflow file in the library and report all structural
problems at once. Exit 1 if any are found.
quickflow help | -h | --help Usage. Exit 0.
quickflow version | --version Version.
Flags may be written before or after the positional workflow name.
-------------------------------------------------------------------------------
WORKFLOW FILE FORMAT
Any *.json file directly inside the library directory:
{
"name": "onboard-teammate",
"description": "Create accounts and send the welcome pack.",
"params": [
{"name": "username", "type": "string", "required": true,
"description": "Corporate login"},
{"name": "team", "type": "enum", "required": true,
"values": ["platform", "data", "design"]},
{"name": "seats", "type": "int", "required": false, "default": 3},
{"name": "welcome", "type": "bool", "required": false, "default": true}
],
"steps": [
{"name": "create account", "command": "provision",
"args": ["--user", "{{username}}", "--team", "{{team}}"]},
{"name": "allocate seats", "command": "licences",
"args": ["--user", "{{username}}", "--count", "{{seats}}"],
"continue_on_error": false}
]
}
Parameter types: string, int, bool, enum.
{{name}} references are substituted in a step's "command" and in each element
of its "args".
-------------------------------------------------------------------------------
SECURITY: PARAMETERS ARE LITERAL ARGV VALUES, NEVER SHELL INPUT
This is the most important property of the tool, so it is stated plainly.
Each step is executed by handing the operating system an explicit argument
vector: the "command" plus the "args" array, each element a separate argument.
No shell is started. QuickFlow never builds a command line by joining strings,
and never calls sh, bash, cmd.exe or any interpreter of its own.
The consequence: a parameter value containing shell metacharacters is delivered
to the program as ordinary text. A value of
; touch /tmp/pwned ;
arrives as one single argument whose characters are exactly those, including
the semicolons and spaces. It does not terminate a command, does not start a
second one, and does not create a file. The same holds for $(...) command
substitution, backticks, pipes, redirections, newlines and quotes.
Two caveats worth being honest about:
* QuickFlow guarantees the value reaches the program intact. What the program
then does with it is that program's business. If a workflow step invokes a
program that itself passes its arguments to a shell, that program reopens
the hole - QuickFlow cannot close it from outside.
* The dry-run listing and `describe` output quote arguments so a human can see
where each one begins and ends. That quoting is cosmetic. It is display
only, and nothing printed by QuickFlow is ever fed back to a shell.
-------------------------------------------------------------------------------
DRY RUN AND --apply
Running a workflow executes commands, so `run` defaults to a dry run.
Without --apply: the resolved parameters and the fully substituted argv of
every step are printed, nothing is executed, and no ledger entry is written.
With --apply: the steps execute in order. A step's failure stops the run and
the command exits 1, unless that step declares "continue_on_error": true, in
which case the run continues and the failure is still recorded in the ledger
and still makes the overall result "failed".
Steps that never ran because an earlier step failed are recorded with status
"skipped".
-------------------------------------------------------------------------------
RUN LEDGER
Every applied run appends exactly one JSON object, on one line, to the ledger
file (JSON Lines). Default path: /quickflow-ledger.jsonl. Override
with --ledger.
Each line records: timestamp (UTC, RFC 3339), workflow name, library path, the
resolved parameters after defaults were applied, every step with its final
command and argv, per-step status (ok / failed / skipped) and exit code, the
overall result, the run duration, and the tool version.
The file is only ever opened for append. Existing bytes are never rewritten,
so earlier lines stay byte-identical as the ledger grows. Dry runs write
nothing. Runs rejected during parameter validation write nothing.
-------------------------------------------------------------------------------
VALIDATION
Parameter validation, before anything executes. All problems are reported at
once, then the command exits 1:
* a required parameter that was not supplied
* a value of the wrong type (e.g. "abc" for an int)
* an enum value not in the declared list - the message lists what is allowed
* a --set key the workflow does not declare - the message lists what it does
Library validation (`validate`), also reported all at once:
* malformed JSON
* two workflows sharing a name
* a workflow with no name, or with no steps
* a step with no command
* a parameter with an unknown type, or an enum with no values
* a parameter declared twice, or required while also carrying a default
* a step referencing {{something}} the workflow does not declare
-------------------------------------------------------------------------------
EXIT STATUS
0 success, or an explicit help request
1 usage error, parameter validation failure, library validation failure,
unknown workflow, unreadable or empty library, or a failed step
-------------------------------------------------------------------------------
WHAT IS IMPLEMENTED
* A shared library that is a plain directory of *.json workflow files.
* Declared parameters with types string, int, bool and enum; required flags,
defaults, allowed values, and per-parameter descriptions.
* {{param}} substitution into a step's command and into each argument.
* Full parameter validation before execution, reporting every problem.
* Dry run by default; execution only under --apply.
* Ordered step execution via explicit argv, with no shell anywhere.
* Per-step continue_on_error.
* Append-only JSON Lines run ledger.
* Structural validation of an entire library in one pass.
* --json output for list, describe, run and validate.
* Single static binary, Go standard library only, no configuration files and
no network access of any kind.
-------------------------------------------------------------------------------
WHAT IS NOT IMPLEMENTED
Be clear about the boundaries before putting this in front of a team.
* The library is a DIRECTORY OF FILES, not a networked service. There is no
server, no accounts, no permissions and no authentication. Anyone who can
write to the directory can change what a workflow does, and anyone who can
read it can run any workflow in it. Access control is whatever the
filesystem or the shared drive provides, and nothing more.
* The ledger is a local append-only text file. It is not tamper-evident:
there are no signatures or hash chaining, and anyone with write access to
the file can edit it after the fact. It is an audit aid, not an audit
guarantee. Concurrent runs from several machines onto one shared ledger
file are not coordinated.
* No secret handling. Parameter values are written to the ledger verbatim, so
passing a password or token as a parameter puts it in the ledger in clear
text. Do not do that yet.
* No approval gates. --apply is the only gate, and it is per-invocation.
A destructive step cannot currently require a second person's sign-off.
* No scheduling, no triggers, no watching. Runs happen when someone runs them.
* No conditionals, loops, branching, retries, timeouts or parallelism in a
workflow. Steps are a flat list executed once, in order.
* No rollback or compensation. If step four fails, steps one to three are not
undone.
* No remote execution. Every step runs as the invoking user on the local
machine, with that user's environment and privileges. There is no sandbox
and no restriction on which programs a workflow may run - a workflow file
is as trusted as any script, so review one before running it.
* No output capture beyond the console. Step stdout and stderr are shown and
combined, but are not stored in the ledger or written to per-run log files.
* No nesting: a workflow cannot call another workflow.
* No versioning of workflow definitions. The ledger records which workflow
ran, not the exact text of the file at the time it ran.
* Only files directly inside the library directory are read; subdirectories
are ignored.
-------------------------------------------------------------------------------
ROADMAP
1. A real workflow server with per-user permissions: who may see, edit and
run each workflow, backed by accounts rather than directory permissions,
with a central ledger the runners cannot rewrite.
2. Approval gates before destructive steps: a step may be marked as requiring
sign-off, and the run pauses until a second, authorised person approves,
with the approver recorded in the ledger.
3. Secret handling: parameters declared as secrets, resolved from a keychain
or secret store at run time, masked in all output, and recorded in the
ledger only as a reference so credentials never land in the audit trail.
4. Scheduled runs: recurring executions of a parameterised workflow with a
fixed parameter set, producing the same ledger entries as a manual run.
-------------------------------------------------------------------------------
BINARIES
dist/quickflow-linux-amd64
dist/quickflow-darwin-amd64
dist/quickflow-darwin-arm64
dist/quickflow-windows-amd64.exe
Build from source with the Go toolchain and no network access:
go build -o quickflow .
Go standard library only. No third-party dependencies.