Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b174c8c299 | |||
| 2fce529edc | |||
| 61dcafe871 |
74
README.md
74
README.md
@@ -8,7 +8,7 @@ root-owned application state.
|
||||
## Variables
|
||||
|
||||
```yaml
|
||||
scriptorium_version: v0.13.0
|
||||
scriptorium_version: v0.15.0
|
||||
scriptorium_repository_url: https://gitea.maximumdirect.net/eric/scriptorium.git
|
||||
scriptorium_source_dir: /usr/local/src/scriptorium
|
||||
scriptorium_binary_path: /usr/local/bin/scriptorium
|
||||
@@ -20,6 +20,7 @@ scriptorium_config_owner: root
|
||||
scriptorium_config_group: root
|
||||
scriptorium_config_directory_mode: "0755"
|
||||
scriptorium_config_file_mode: "0644"
|
||||
scriptorium_configkit_imports: null
|
||||
scriptorium_prompt_dir: null
|
||||
scriptorium_profile_dir: null
|
||||
scriptorium_schema_dir: null
|
||||
@@ -30,6 +31,7 @@ scriptorium_server_max_artifact_bytes: null
|
||||
scriptorium_server_max_response_bytes: null
|
||||
scriptorium_defaults_render_format: null
|
||||
scriptorium_backends: null
|
||||
scriptorium_transient_retries: null
|
||||
```
|
||||
|
||||
When `scriptorium_manage_build_dependencies` is `false`, Git and the executable
|
||||
@@ -62,6 +64,57 @@ Backend entries may name a credential environment variable through
|
||||
does not install prompt, profile, or schema content and does not manage a
|
||||
service.
|
||||
|
||||
`scriptorium_configkit_imports` accepts a list of native ConfigKit import
|
||||
mappings. Paths and globs are interpreted by Scriptorium relative to the
|
||||
configuration root; the caller supplies and owns the referenced files. For
|
||||
example, an inventory may select a caller-managed fragment:
|
||||
|
||||
```yaml
|
||||
scriptorium_configkit_imports:
|
||||
- path: fragments/server.yml
|
||||
scriptorium_transient_retries: 0
|
||||
```
|
||||
|
||||
Both settings are omitted when `null`. Setting `scriptorium_transient_retries`
|
||||
to `0` disables additional transient attempts; omission leaves the retry
|
||||
budget with Scriptorium and PromptKit. Leave these newer fields unset when
|
||||
selecting an older Scriptorium version that does not support them.
|
||||
|
||||
## Upgrading to v0.15.0
|
||||
|
||||
The intervening v0.14.0 release adopted ConfigKit. It rejects empty
|
||||
configuration files, unknown fields, multiple YAML documents, and YAML
|
||||
anchors or aliases. Use `{}` when no application settings are selected;
|
||||
the role already renders that document. See the tagged
|
||||
[configuration reference](https://gitea.maximumdirect.net/eric/scriptorium/src/tag/v0.15.0/docs/config.md)
|
||||
and [migration notes](https://gitea.maximumdirect.net/eric/scriptorium/src/tag/v0.14.0/docs/releases/v0.14.0.md)
|
||||
for the complete acceptance and precedence rules.
|
||||
|
||||
ConfigKit imports are resolved relative to the selected configuration file's
|
||||
canonical directory. ConfigKit files under `overlays/` are selected by the
|
||||
application's `--config-overlay` flag; they are separate from PromptKit LLM
|
||||
profiles selected through profile settings and `profile_dir`. Application
|
||||
path *values* such as `prompt_dir` and `profile_dir` remain relative to the
|
||||
Scriptorium process working directory, even when declared in an import or
|
||||
overlay. This role only supplies import entries; callers own referenced files
|
||||
and runtime overlay selection.
|
||||
|
||||
PromptKit now makes up to two additional attempts by default for eligible
|
||||
transient provider responses. `scriptorium_transient_retries` can change that
|
||||
application budget, while repair generations have separate budgets. Review
|
||||
provider call count and latency when upgrading; see the tagged
|
||||
[retry guidance](https://gitea.maximumdirect.net/eric/scriptorium/src/tag/v0.15.0/docs/config.md#credentials-and-outbound-behavior).
|
||||
The legacy `deepseek-3-2`, `deepseek-4-flash`, and `deepseek-4-pro` catalog
|
||||
profile IDs were removed without aliases; select a maintained profile when
|
||||
updating callers.
|
||||
|
||||
Scriptorium v0.15.0's application source and binaries are distributed under
|
||||
GPL-3.0-or-later; its tagged [copyright](https://gitea.maximumdirect.net/eric/scriptorium/src/tag/v0.15.0/COPYRIGHT),
|
||||
[license](https://gitea.maximumdirect.net/eric/scriptorium/src/tag/v0.15.0/LICENSE),
|
||||
and [attribution notices](https://gitea.maximumdirect.net/eric/scriptorium/src/tag/v0.15.0/docs/oss/attribution.md)
|
||||
describe that grant and separately attributed material. The Ansible role's
|
||||
own [CC0 license](LICENSE) is unchanged.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
@@ -73,14 +126,17 @@ service.
|
||||
## Validation
|
||||
|
||||
The repository-local integration suite installs its pinned collection and runs
|
||||
syntax checking and production-profile lint. It applies the default role, uses
|
||||
an offline native profile inspection with the managed configuration, and then
|
||||
requires clean repeated convergence. It also combines missing-binary recovery
|
||||
with a caller-supplied Go executable while dependency management is disabled,
|
||||
and covers one representative configuration with null omission, intentional
|
||||
zero and false values, backend pass-through, and offline native inspection. It
|
||||
mutates only the managed source, binary, configuration, and a private temporary
|
||||
directory, then restores the default deployment during cleanup.
|
||||
syntax checking and production-profile lint. It applies the default role,
|
||||
validates the managed application configuration with the native CLI, performs
|
||||
offline profile inspection, and requires clean repeated convergence. It also
|
||||
combines missing-binary recovery with a caller-supplied Go executable while
|
||||
dependency management is disabled. Representative configuration coverage checks
|
||||
null omission, intentional zero and false values, backend pass-through, native
|
||||
validation, and offline profile inspection. A caller-owned fragment exercises
|
||||
relative imports and explicit retry zero through native `config show`. The
|
||||
suite restores the default configuration during cleanup. These offline checks
|
||||
do not establish provider connectivity, service operation, or suite-level
|
||||
compatibility.
|
||||
|
||||
```sh
|
||||
tests/integration
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
scriptorium_version: v0.13.0
|
||||
scriptorium_version: v0.15.0
|
||||
scriptorium_repository_url: https://gitea.maximumdirect.net/eric/scriptorium.git
|
||||
scriptorium_source_dir: /usr/local/src/scriptorium
|
||||
scriptorium_binary_path: /usr/local/bin/scriptorium
|
||||
@@ -11,6 +11,7 @@ scriptorium_config_owner: root
|
||||
scriptorium_config_group: root
|
||||
scriptorium_config_directory_mode: "0755"
|
||||
scriptorium_config_file_mode: "0644"
|
||||
scriptorium_configkit_imports: null
|
||||
scriptorium_prompt_dir: null
|
||||
scriptorium_profile_dir: null
|
||||
scriptorium_schema_dir: null
|
||||
@@ -21,3 +22,4 @@ scriptorium_server_max_artifact_bytes: null
|
||||
scriptorium_server_max_response_bytes: null
|
||||
scriptorium_defaults_render_format: null
|
||||
scriptorium_backends: null
|
||||
scriptorium_transient_retries: null
|
||||
|
||||
@@ -39,6 +39,10 @@ argument_specs:
|
||||
scriptorium_config_file_mode:
|
||||
type: str
|
||||
required: true
|
||||
scriptorium_configkit_imports:
|
||||
type: list
|
||||
elements: dict
|
||||
required: false
|
||||
scriptorium_prompt_dir:
|
||||
type: path
|
||||
required: false
|
||||
@@ -69,3 +73,6 @@ argument_specs:
|
||||
scriptorium_backends:
|
||||
type: dict
|
||||
required: false
|
||||
scriptorium_transient_retries:
|
||||
type: int
|
||||
required: false
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
{% if scriptorium_prompt_dir is none and scriptorium_profile_dir is none and scriptorium_schema_dir is none and scriptorium_server_addr is none and scriptorium_server_artifact_root is none and scriptorium_server_max_request_bytes is none and scriptorium_server_max_artifact_bytes is none and scriptorium_server_max_response_bytes is none and scriptorium_defaults_render_format is none and scriptorium_backends is none %}
|
||||
{% if (
|
||||
scriptorium_configkit_imports is none
|
||||
and scriptorium_prompt_dir is none
|
||||
and scriptorium_profile_dir is none
|
||||
and scriptorium_schema_dir is none
|
||||
and scriptorium_server_addr is none
|
||||
and scriptorium_server_artifact_root is none
|
||||
and scriptorium_server_max_request_bytes is none
|
||||
and scriptorium_server_max_artifact_bytes is none
|
||||
and scriptorium_server_max_response_bytes is none
|
||||
and scriptorium_defaults_render_format is none
|
||||
and scriptorium_backends is none
|
||||
and scriptorium_transient_retries is none
|
||||
) %}
|
||||
{}
|
||||
{% else %}
|
||||
{% if scriptorium_configkit_imports is not none %}
|
||||
configkit:
|
||||
imports: {{ scriptorium_configkit_imports | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_prompt_dir is not none %}
|
||||
prompt_dir: {{ scriptorium_prompt_dir | to_json }}
|
||||
{% endif %}
|
||||
@@ -35,4 +52,7 @@ defaults:
|
||||
{% if scriptorium_backends is not none %}
|
||||
backends: {{ scriptorium_backends | to_json }}
|
||||
{% endif %}
|
||||
{% if scriptorium_transient_retries is not none %}
|
||||
transient_retries: {{ scriptorium_transient_retries | to_json }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
@@ -16,6 +16,8 @@ ansible_playbook="$workspace_venv/bin/ansible-playbook"
|
||||
binary_path=/usr/local/bin/scriptorium
|
||||
config_path=/usr/local/etc/scriptorium/config.yml
|
||||
profile_dir="$test_tmp/profiles"
|
||||
import_root="$test_tmp/config-root"
|
||||
import_config_path="$import_root/config.yml"
|
||||
|
||||
cleanup() {
|
||||
exit_status=$?
|
||||
@@ -55,6 +57,15 @@ cd "$repository_root"
|
||||
|
||||
baseline_log="$test_tmp/baseline.log"
|
||||
run_converge "$baseline_log"
|
||||
"$binary_path" config validate --config "$config_path"
|
||||
"$workspace_venv/bin/python" -c '
|
||||
import sys
|
||||
import yaml
|
||||
with open(sys.argv[1], encoding="utf-8") as config_file:
|
||||
config = yaml.safe_load(config_file)
|
||||
assert "configkit" not in config
|
||||
assert "transient_retries" not in config
|
||||
' "$config_path"
|
||||
"$binary_path" inspect profile --config "$config_path" \
|
||||
--profile-dir "$profile_dir" --profile endpoint-profile
|
||||
baseline_repeat_log="$test_tmp/baseline-repeat.log"
|
||||
@@ -90,9 +101,44 @@ representative_args=(
|
||||
)
|
||||
representative_log="$test_tmp/representative.log"
|
||||
run_converge "$representative_log" "${representative_args[@]}"
|
||||
"$binary_path" config validate --config "$config_path"
|
||||
"$binary_path" inspect profile --config "$config_path" --profile backend-profile
|
||||
"$ansible_playbook" -i "$inventory" \
|
||||
-e "scriptorium_test_profile_dir=$profile_dir" "$verify_config"
|
||||
representative_repeat_log="$test_tmp/representative-repeat.log"
|
||||
run_converge "$representative_repeat_log" "${representative_args[@]}"
|
||||
require_clean_recap "$representative_repeat_log"
|
||||
|
||||
mkdir -p "$import_root/fragments"
|
||||
printf '%s\n' \
|
||||
'server:' \
|
||||
' addr: 127.0.0.1:18081' > "$import_root/fragments/server.yml"
|
||||
import_args=(
|
||||
-e "scriptorium_config_path=$import_config_path"
|
||||
-e "scriptorium_config_owner=$(id -un)"
|
||||
-e "scriptorium_config_group=$(id -gn)"
|
||||
-e '{"scriptorium_configkit_imports": [{"path": "fragments/server.yml"}], "scriptorium_transient_retries": 0}'
|
||||
)
|
||||
import_log="$test_tmp/import.log"
|
||||
run_converge "$import_log" "${import_args[@]}"
|
||||
"$binary_path" config validate --config "$import_config_path"
|
||||
"$workspace_venv/bin/python" -c '
|
||||
import sys
|
||||
import yaml
|
||||
with open(sys.argv[1], encoding="utf-8") as config_file:
|
||||
config = yaml.safe_load(config_file)
|
||||
assert config["configkit"]["imports"] == [{"path": "fragments/server.yml"}]
|
||||
assert config["transient_retries"] == 0
|
||||
assert "server" not in config
|
||||
' "$import_config_path"
|
||||
"$binary_path" config show --config "$import_config_path" | \
|
||||
"$workspace_venv/bin/python" -c '
|
||||
import sys
|
||||
import yaml
|
||||
config = yaml.safe_load(sys.stdin)
|
||||
assert config["server"]["addr"] == "127.0.0.1:18081"
|
||||
assert config["transient_retries"] == 0
|
||||
'
|
||||
import_repeat_log="$test_tmp/import-repeat.log"
|
||||
run_converge "$import_repeat_log" "${import_args[@]}"
|
||||
require_clean_recap "$import_repeat_log"
|
||||
|
||||
Reference in New Issue
Block a user