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.