Installer Specifications¶
Target Location¶
The installer shall determine the repository root by traversing parent
directories from the current working directory until a |
The installer shall present a Copier prompt
On failure, the prompt shall be repeated with an inline error. The resolved
absolute path shall be stored as |
Epic Management¶
The installer template shall define epics via a YAML list in
epics:
- id: "target_location"
title: "Target Location"
default: true
- id: "conflict_detection"
title: "Conflict Detection"
default: true
The |
Copier shall render a |
Each RST snippet belonging to an epic shall be wrapped in a Jinja2 conditional in the template source: {% if "conflict_detection" in selected_epics %}
.. flowstory:: Conflict detection
:id: FLST_UBFLOW_INST_10
...
{% endif %}
Deactivated epics produce no output in the rendered file. |
Determinism and Verification¶
The installer shall invoke Copier against the locally extracted package
directory (see copier copy \
--trust \
--data package_name=<name> \
--data package_version=<version> \
<extracted_tmp_dir> \
<target_abs_path>
No prompts shall appear in replay mode. Two invocations with identical
package zip contents and |
After a successful installation, the installer shall write a manifest file
{
"schema_version": 1,
"package_source": "families://aspice",
"package_version": "0.1.0",
"installed_at": "2026-03-14T10:00:00Z",
"files": {
"relative/path/to/file.rst": "sha256:<hex>"
}
}
|
A FAIL relative/path/to/file.rst (expected abc123, got def456)
The command exits with code 0 if all digests match, code 2 otherwise. |
Target Folder Layout¶
The Copier template _subdirectory: "template"
so that all rendered files are output exclusively inside the install
directory. The installer shall always place the family into the fixed
subdirectory <target_abs_path>/
└── ubflow/
└── <family_name>/
├── .ubflow-answers.yml
├── .ubflow-manifest.json
├── index.rst
├── user_stories.rst
├── specs.rst
├── instructions.rst
├── skills.rst
└── traceability.rst
No files outside |
Template and Version Selection¶
The installer shall read the package version from the
copier copy --trust \
--data package_version=<value from ubflow_package.json> \
<extracted_tmp_dir> <target_abs_path>
No |
Partial Agent Selection¶
Template agent subdirectories are rendered only when the agent ID appears
in {% if "sys2" in selected_agents %}
{%- include "agents/sys2/index.rst.jinja" %}
{% endif %}
At least one agent must be selected; Copier validator raises a
|
Prerequisite Check and Auto-Install¶
The installer template shall include a Copier task hook
The script prints all failures and exits with code 1 if any check fails, preventing Copier from rendering the template. |
When python -m pip install "sphinx-needs>=2.0.0" "copier>=9.0.0"
On decline it shall print the manual install command and exit with code 1.
Missing system dependencies ( |
Update and Upgrade¶
To upgrade an existing installation, the installer shall:
copier copy \
--trust --overwrite --defaults \
--data package_version=<new_version> \
<new_extracted_tmp_dir> \
<target_abs_path>
Copier performs a three-way merge: base = previous template version,
ours = current installed files, theirs = new package. Merge conflicts
are surfaced as standard diff conflict markers in the affected files.
No |
Before upgrading, the installer shall run Copier in pretend mode against the new extracted temporary directory: copier copy \
--trust --pretend --overwrite --defaults \
--data package_version=<new_version> \
<new_extracted_tmp_dir> \
<target_abs_path>
and display the resulting diff. The installer shall require the developer
to enter |
Conflict Detection¶
The installer task hook CONFLICT FLST_UBFLOW_INST_01 found in: docs/my_stories.rst:14
The hook exits with code 1 when one or more conflicts exist, blocking the Copier render step. |
Before writing files, EXISTS docs/aspice/index.rst — overwrite? [y/N]
Files answered with |
Rollback and Uninstall¶
A SKIPPED relative/path/file.rst (modified since install — remove manually)
|
The Copier post-generation task Installation failed. All written files have been removed.
Repository state is unchanged.
|
Configuration Persistence¶
Copier shall write the answers file to
_answers_file: ".copier-answers.yml"
The file shall contain at minimum: package_name: "aspice"
package_version: "0.1.0"
target_docs_path: "docs/"
selected_agents:
- orchestrator
- sys2
selected_epics:
- core
- sw_change
family_name: "aspice"
No URL or git commit reference is stored. The installed version is
recorded via |
When |
Post-Install Validation¶
Every ubFlow package directory shall contain a file
{
"schema_version": 1,
"package_name": "aspice",
"package_version": "0.1.0",
"display_name": "ASPICE Agent Family",
"description": "...",
"directories": [
{
"id": "orchestrator",
"title": "Orchestrator",
"description": "Main orchestrator agent",
"default": true
}
],
"epics": [
{
"id": "core",
"title": "Core Workflows",
"description": "Fundamental process workflows",
"default": true
}
]
}
The |
The installer shall locate the family source by searching the following locations in order, returning the first that exists:
If no match is found in any location, the installer shall exit with code 1 and list all searched paths. |
Flow Spec: Family source preparation (directory pass-through or zip extraction) FLSP_UBFLOW_INST_026
|
After finding the family source (see Directory source: the directory is used directly as the Copier template source. No extraction is performed and no cleanup is needed after Copier exits. Zip source: the zip file is extracted to a system temporary directory
( The preparation sequence is: source = resolve_family(family_name, repo_root, extension_dir)
work_dir, was_extracted = prepare_source(source)
try:
# read ubflow_package.json from work_dir
# invoke copier copy work_dir → target_abs_path
finally:
if was_extracted:
cleanup_source(work_dir)
|
The Copier post-generation task UNDEF FLSP_UBFLOW_INST_999 referenced in: aspice/specs.rst:42
The task exits with code 1 if undefined references exist. |
After the undefined-reference scan passes, sphinx-build -b html -W --keep-going \
<docs_root> <docs_root>/_build/html
where |
ubFlow Agent Stub¶
During every install or upgrade the installer SHALL write the file
The file content SHALL be exactly: ---
description: ubFlow — needs-driven agent design for GitHub Copilot
applyTo: '**'
---
Fetch your full instruction and skill set from the ubCode MCP server
before doing anything else:
1. Call `get_schema_for_need_filter` with `agent="ubflow"` to verify
the ubCode extension is reachable.
2. Call `query_needs` with `type="flowinst"`, `tags=["ubflow"]`, and
`agent="ubflow"` to load all binding instructions.
3. Call `query_needs` with `type="flowskill"`, `tags=["ubflow"]`, and
`agent="ubflow"` to load all skills.
If any call returns `{"error": "unknown_agent"}` or fails, stop and
ask the user to install or update the ubCode VS Code extension.
The operation SHALL be idempotent: if the file already exists with identical content, nothing is changed. If it exists with different content it SHALL be overwritten and the change reported to the user. |
Flow Spec: Installer creates the companion bootstrap instructions file idempotently FLSP_UBFLOW_INST_028
|
During every install or upgrade the installer SHALL write the file
The file content SHALL be exactly: ---
applyTo: '**'
---
## ubFlow Bootstrap — <family_name> family
When operating as `@<family_name>`:
1. Call `mcp_ubcode_get_schema_for_need_filter` with
`file_path: ubflow/<family_name>/ubproject.toml`.
2. Call `mcp_ubcode_get_data_for_single_need` with
`id: <ORCHESTRATOR_AGT_ID>`.
3. Load every need linked via `:applies:` and `:employs:`.
4. Only then respond to the user request.
Do **not** skip these steps. If any MCP call fails, halt and ask
the user to check the ubCode extension.
The The operation SHALL be idempotent: if the file already exists with identical content, nothing is changed. If it exists with different content it SHALL be overwritten and the change reported to the user. The file SHALL not be removed during uninstall of the family. |