diff --git a/.github/workflows/spiral-integration.yml b/.github/workflows/spiral-integration.yml new file mode 100644 index 0000000..c13b7e5 --- /dev/null +++ b/.github/workflows/spiral-integration.yml @@ -0,0 +1,41 @@ +name: Spiral integration + +permissions: + contents: read + +on: + pull_request: + merge_group: + types: [checks_requested] + +jobs: + spiral-integration: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + submodules: recursive + + - uses: actions/setup-node@v7 + with: + node-version: '24' + + - uses: actions/setup-python@v7 + with: + python-version: '3.13' + + - run: pip install -r .spiral-core/requirements.txt + + - if: github.event_name == 'pull_request' + run: >- + node .spiral-core/bin/spiral.mjs validate integration + --base '${{ github.event.pull_request.base.sha }}' + --head '${{ github.event.pull_request.head.sha }}' + --base-branch '${{ github.event.pull_request.base.ref }}' + --head-branch '${{ github.event.pull_request.head.ref }}' + + # Candidate cycle closure/branch correspondence was checked on pull_request. + # Validate the exact queued combined snapshot rather than reconstructing only the individual PR. + - if: github.event_name == 'merge_group' + run: python .spiral-core/bin/spiral-rdf.py --repo . --tree '${{ github.sha }}' diff --git a/.spiral-core b/.spiral-core index 3111b78..8d4b2c7 160000 --- a/.spiral-core +++ b/.spiral-core @@ -1 +1 @@ -Subproject commit 3111b784531e327da75801f5ba8b61e891341d5f +Subproject commit 8d4b2c738a413abd4cccca740ce958f486e5f7af diff --git a/.spiral/cycles/CYC-018.md b/.spiral/cycles/CYC-018.md new file mode 100644 index 0000000..57e5499 --- /dev/null +++ b/.spiral/cycles/CYC-018.md @@ -0,0 +1,174 @@ +--- +id: CYC-018 +--- + +# Cycle: Spiral Core Process Update + +Repository branch: `spiral/CYC-018-spiral-core-update` +Branch verified: verified on 2026-08-18 with `git branch --show-current`, branched from `master` after accepted CYC-017 was merged. + +## Analyze + +Project state / prior evaluation that makes this cycle relevant: + +SimplyStore uses `.spiral-core` as its installed Spiral Developer process source. The latest accepted SimplyStore cycle is CYC-017, and there is no active product cycle. The human requested updating `.spiral-core` and adjusting local process before the next durability/product cycle. + +Nearest important risk / uncertainty / desired movement: + +If the local process remains behind the installed Spiral core, future cycles may use outdated collaboration, validation, or artifact guidance. Conversely, blindly adopting upstream changes without checking their relevance can add local ceremony or contradict SimplyStore's established working defaults. + +Relevant human direction / feedback: + +The human explicitly requested: "Before the next cycle, please update .spiral-core and adjust the process." + +Continuation on 2026-08-19: the human asked to update `.spiral-core` again and follow any new instructions. + +Governing higher-level plan / direction: + +This is a process-maintenance cycle governed by Spiral's process-evolution and Git history rules. It intentionally precedes the next product durability cycle. + +Current position in that plan: + +CYC-017 is accepted and merged. The next product direction remains durability integrity/tamper detection, but this cycle temporarily updates the process substrate first. + +## Plan + +### Cycle goal + +Update `.spiral-core` to the latest upstream version available from `github.com/muze-labs/spiral-developer`, inspect the process changes, and adjust SimplyStore's local process/project context where those changes materially apply. + +### Why now / why this cycle boundary + +The human asked to do this before the next product cycle. Keeping it separate avoids mixing process-adoption changes with durability/runtime behavior changes. + +### Plan continuity decision + +Revise local process substrate before continuing the durability roadmap. This does not replace the next product goal; it prepares the repository to run it under the current Spiral process. + +### Current starting evidence + +- `.spiral-core` is currently at `3111b784531e327da75801f5ba8b61e891341d5f`. +- `.spiral/project-context.md` records no active cycle and CYC-017 as latest accepted. +- `master` is clean and contains the CYC-017 merge. + +### Evaluation basis + +- `.spiral-core` is updated to the latest fetched upstream commit. +- Upstream changes since the prior core commit are inspected and summarized. +- Local `AGENTS.md` and/or `.spiral/project-context.md` are adjusted only where the upstream process changes materially apply to SimplyStore. +- No SimplyStore runtime/product behavior changes. +- Relevant process/provenance checks pass or any limits are recorded. + +### Likely work + +- Fetch `.spiral-core` upstream. +- Inspect commit log and changed files since the current submodule commit. +- Move the submodule pointer. +- Read changed upstream docs/prompts/cultures/profiles that affect local work. +- Update local process context/instructions where needed. +- Record implementation/evidence artifacts if the changes are material. + +### Explicit non-goals + +- Start the integrity/tamper-detection product cycle. +- Change SimplyStore runtime code, tests, durable format, REST API, or JavaScript query API. +- Rewrite existing cycle history. +- Adopt upstream changes locally when they are irrelevant to SimplyStore. + +### Pause / re-plan conditions + +- Upstream process changes materially conflict with existing accepted SimplyStore process commitments. +- The submodule cannot be fetched or checked out. +- The update requires product/runtime changes. + +## Act + +Important artifacts / semantic commits produced: + +- `4cefd007da682ce8ef46ccfc4852882fb34e2003` opened CYC-018 on `spiral/CYC-018-spiral-core-update`. +- `IMP-20260818-09ZEF-1` records the local adoption of `.spiral-core` distributed-development and integration-validation guidance. +- `EVD-20260818-09ZEF-2` records verification of the process update and local validation limits. +- `EVD-20260818-09ZEF-3` records the later Python retry, successful tree/prospective-integration validation, and remaining worktree-validation limitation. +- `EVD-20260819-09ZEF-4` records verification of the later `.spiral-core` update to `8d4b2c738a413abd4cccca740ce958f486e5f7af` and the new Active-cycle integration guard. + +Material implementation decisions or deviations from the initial likely work: + +- `.spiral-core` was updated from `3111b784531e327da75801f5ba8b61e891341d5f` to `b24a5e8e301437561f2ed7e60486014cebae12c6`. +- `.spiral-core` was later updated again from `b24a5e8e301437561f2ed7e60486014cebae12c6` to `8d4b2c738a413abd4cccca740ce958f486e5f7af`. +- Future new artifacts should use worktree-local distributed IDs from `node .spiral-core/bin/spiral.mjs allocate `. +- CYC-018 retains its legacy sequential ID because it was opened before this upstream process change was adopted locally. +- SimplyStore now has a GitHub Actions adapter for Spiral integration validation, but branch protection settings remain outside repository control. +- The old repository-local CYC-016 validator was made tolerant of distributed artifact IDs, while its CYC-016-specific branch/traversal behavior remains a known limit. +- A local `.spiral/vocabulary.ttl` file was added so tree-based validation has the needed causal relation hierarchy when `.spiral-core` appears only as a submodule gitlink. +- The GitHub merge-group workflow validates the merge-group commit tree directly because current worktree validation includes `.spiral-core`'s own Turtle artifacts. +- The pull-request workflow now passes base/head branch names to Spiral integration validation so cycle closure and branch/cycle correspondence can be checked where hosting metadata is available. +- Local process guidance now records the new rule that Active cycle branches do not merge outward and that parallel material revisions of the same governed artifact require explicit convergence lineage with `sd:transforms`. + +Out-of-scope discoveries retained for later: + +- Local Spiral validation requires Python `rdflib`; after retrying Python setup, a temporary virtual environment under `/tmp` worked. +- `node .spiral-core/bin/spiral.mjs validate` still fails in this submodule-consuming repository because it recursively includes `.spiral-core`'s own Turtle artifacts. + +## Evaluate + +Integrated result against cycle goal: + +The cycle goal is met. `.spiral-core` is updated to the latest fetched upstream commit, the upstream distributed-development and integration-validation guidance was inspected, and SimplyStore's local process surface was adjusted where the changes materially apply. + +Evidence / acceptance result: + +`EVD-20260818-09ZEF-2` records the initial verification evidence. `EVD-20260818-09ZEF-3` updates that evidence after Python setup was retried: tree/prospective-integration validation now passes with a temporary virtual environment, while worktree validation remains blocked by upstream submodule scanning behavior. `EVD-20260819-09ZEF-4` verifies the latest core update and confirms that branch-aware integration validation correctly rejected CYC-018 while it remained `sd:Active`. The human accepted the cycle on 2026-08-19. + +Metric or risk movement: + +The risk of future artifact ID conflicts in concurrent work is reduced by adopting worktree-local distributed allocation. The risk of accepting locally valid but integration-invalid Spiral graph changes is reduced by adding a pre-merge integration validation expectation and GitHub workflow adapter. + +The risk of accidentally merging unfinished cycle work is further reduced by adopting the upstream Active-cycle integration guard. The risk of clean Git merges silently combining independent governed-artifact meanings is reduced by recording the explicit-convergence rule in local process context. + +What changed in our understanding: + +Spiral core now treats integration context as a brownfield intake topic. SimplyStore's previous intake was still materially complete, but needed an added integration-context section. + +Surprises / model mismatches: + +The current environment can run the new Spiral RDF validator through a temporary `/tmp` virtual environment. The remaining validator mismatch is not Python setup: worktree validation recursively includes `.spiral-core`'s own Turtle files and reports duplicate artifact IDs in this submodule-consuming repository. + +Known compromises: + +- CYC-018 keeps its legacy sequential ID because it was opened before the distributed-ID process was adopted locally. +- Branch protection/required-check settings are external to the repository and remain unknown. +- The old repository-local validator remains CYC-016-specific. +- Local worktree validation with the new core CLI remains unsuitable until upstream excludes nested process repositories or accepts an explicit graph root. + +Unresolved issues within current goal: + +No repository changes remain. Local tree/prospective-integration validation works with a prepared Python environment; local worktree validation remains an upstream tooling limitation recorded for follow-up. + +Candidate next-cycle inputs: + +- Continue the durability roadmap with integrity/tamper detection after CYC-018 is accepted and merged. +- Consider configuring repository branch protection so the new Spiral integration workflow is required. + +Human evaluation / feedback: + +Accepted by the human on 2026-08-19 after reviewing the summary of Spiral process changes. The accepted result is that SimplyStore now follows the updated distributed Spiral process: distributed artifact allocation, branch-aware integration validation, no outward merge of Active cycle branches, and explicit convergence lineage for parallel governed-artifact revisions. + +Cycle accepted, still open, or deliberately re-planned: + +Accepted. Ready for prospective integration validation against the current `master`. + +## Process learning + +What context/constraint/evaluation helped: + +The new distributed-ID allocator immediately prevented us from continuing the old global-next-number habit for new implementation/evidence artifacts. + +What bookkeeping was useless: + +None identified; this cycle was process-maintenance work, so the process bookkeeping itself was the subject of the change. + +What should the environment learn from this cycle: + +Future SimplyStore Spiral artifacts should be allocated through the core CLI. Future integration should validate the candidate against the current target, not only the branch snapshot. + +Later core update added two important distributed-process lessons: cycle acceptance must be recorded before outward integration, and Git textual merge is not enough evidence when two histories materially changed the same governed artifact. diff --git a/.spiral/cycles/CYC-018.ttl b/.spiral/cycles/CYC-018.ttl new file mode 100644 index 0000000..6f53463 --- /dev/null +++ b/.spiral/cycles/CYC-018.ttl @@ -0,0 +1,9 @@ +@prefix sd: . +@prefix dcterms: . +@prefix project: . + +project:CYC-018 + a sd:Cycle ; + dcterms:identifier "CYC-018" ; + sd:repositoryPath ".spiral/cycles/CYC-018.md" ; + sd:status sd:Accepted . diff --git a/.spiral/evidence/EVD-20260818-09ZEF-2.md b/.spiral/evidence/EVD-20260818-09ZEF-2.md new file mode 100644 index 0000000..e344842 --- /dev/null +++ b/.spiral/evidence/EVD-20260818-09ZEF-2.md @@ -0,0 +1,88 @@ +--- +id: EVD-20260818-09ZEF-2 +--- + +# Verification Evidence: Spiral Core Process Update + +## Claim being verified + +`IMP-20260818-09ZEF-1` updates SimplyStore's local Spiral Developer process adoption to `.spiral-core` commit `b24a5e8e301437561f2ed7e60486014cebae12c6` and applies the upstream distributed-development and integration-validation process changes that matter locally. + +## Why this evidence exists + +The human requested updating `.spiral-core` and adjusting the local process before the next product durability cycle. The upstream core update changes how new artifact IDs should be allocated and adds a prospective integration validation boundary, both of which affect future SimplyStore cycles. + +## Implementation under test + +| Artifact/path/symbol | Commit | Role | +|---|---|---| +| `.spiral-core` | `569e0eaab953b6294ba1c9e04204b25f95612df4` | Submodule pointer updated to upstream `b24a5e8e301437561f2ed7e60486014cebae12c6`. | +| `AGENTS.md` | `278a9cacc55464644276f3ef904a646b91998300` | Local instructions updated for distributed artifact allocation and pre-merge validation. | +| `.spiral/project-context.md` | `278a9cacc55464644276f3ef904a646b91998300` | Project context updated with new core hash, integration context, allocator direction, and local validator dependency limit. | +| `.github/workflows/spiral-integration.yml` | `278a9cacc55464644276f3ef904a646b91998300` | GitHub adapter for pull-request and merge-group Spiral validation. | +| `scripts/validate-spiral-provenance.mjs` | `569e0eaab953b6294ba1c9e04204b25f95612df4` | Legacy CYC-016 validator made tolerant of distributed artifact IDs. | +| `.spiral/implementations/IMP-20260818-09ZEF-1.*` | `569e0eaab953b6294ba1c9e04204b25f95612df4` | Process-adoption implementation provenance. | + +## Evidence method + +- [x] Automated test +- [x] Property/invariant check +- [x] Static analysis +- [ ] Benchmark +- [x] Manual observation +- [ ] Integration exercise +- [ ] Other: + +## Result + +Commands run: + +```text +git -C .spiral-core fetch origin +git -C .spiral-core log --oneline --decorate HEAD..origin/main +git -C .spiral-core diff --name-status HEAD..origin/main +git -C .spiral-core checkout origin/main +git -C .spiral-core rev-parse HEAD +node .spiral-core/bin/spiral.mjs --help +node .spiral-core/bin/spiral.mjs status +node .spiral-core/bin/spiral.mjs workspace init +node .spiral-core/bin/spiral.mjs allocate IMP +node .spiral-core/bin/spiral.mjs allocate EVD +npm test +git diff --check +grep -R -nE "gitCommit \"[0-9a-f]{7,39}\"" .spiral/implementations/IMP-20260818-09ZEF-1.ttl +git merge-base --is-ancestor 278a9cacc55464644276f3ef904a646b91998300 HEAD +git merge-base --is-ancestor 4cefd007da682ce8ef46ccfc4852882fb34e2003 HEAD +node scripts/validate-spiral-provenance.mjs +node .spiral-core/bin/spiral.mjs validate +``` + +Results: + +- `.spiral-core` updated from `3111b784531e327da75801f5ba8b61e891341d5f` to `b24a5e8e301437561f2ed7e60486014cebae12c6`. +- Upstream changes since the prior adopted core commit add distributed artifact identity/allocation, a Spiral CLI, prospective integration validation, hosted CI adapter examples, and updated intake/git/review guidance. +- Worktree-local allocator namespace initialized as `09ZEF`; allocated IDs were `IMP-20260818-09ZEF-1` and `EVD-20260818-09ZEF-2`. +- `AGENTS.md` now points agents to `docs/distributed-development.md`, instructs future new artifacts to use `node .spiral-core/bin/spiral.mjs allocate `, and records the pre-merge integration validation expectation. +- `.spiral/project-context.md` now records `master` as authoritative integration branch, the history-preserving review/merge boundary, the Spiral integration validation command, the GitHub workflow adapter, and the local validator dependency limitation. +- `.github/workflows/spiral-integration.yml` adapts the upstream GitHub example to this repository's `.spiral-core` submodule path. +- The legacy repository-local validator now accepts distributed artifact IDs, then fails at its known CYC-016-specific branch check: `Expected CYC-016 branch, got spiral/CYC-018-spiral-core-update`. +- The new Spiral core validator could not run locally because Python package `rdflib` is unavailable. +- Attempting `python3 -m pip install --user -r .spiral-core/requirements.txt` failed because the OS is an externally managed Python environment. +- Attempting `python3 -m venv /tmp/simplystore-spiral-venv` failed because `python3-venv` / `ensurepip` is unavailable. +- `uv`, `pipx`, and Python `rdflib` were not installed in this environment. +- `npm test` passed: 16/16 startup durability tests. +- `git diff --check` passed. +- No accidental short Git hashes were found in the new implementation Turtle reference. +- The new implementation Turtle references point to existing ancestor commits. + +## Failure cases / limits + +- Local execution of `node .spiral-core/bin/spiral.mjs validate` still requires a prepared Python environment with `rdflib`. +- The GitHub Actions workflow is only a repository-side adapter. Repository branch protection/required-check settings are external hosting configuration and remain unknown. +- Existing historical artifacts keep their legacy sequential IDs; this is intentional. +- CYC-018 itself keeps a legacy sequential cycle ID because it was opened before the updated distributed-ID process was adopted locally. +- `scripts/validate-spiral-provenance.mjs` remains CYC-016-specific and should not be treated as the general current validator. + +## Evidence quality + +This evidence is sufficient for the process-update claim: the submodule was updated, the upstream process delta was inspected, local instructions/context were adjusted where relevant, the new allocator was initialized and used, the CI adapter was added, product tests still pass, and local validation limitations are explicit rather than hidden. diff --git a/.spiral/evidence/EVD-20260818-09ZEF-2.ttl b/.spiral/evidence/EVD-20260818-09ZEF-2.ttl new file mode 100644 index 0000000..9cec3dc --- /dev/null +++ b/.spiral/evidence/EVD-20260818-09ZEF-2.ttl @@ -0,0 +1,14 @@ +@prefix sd: . +@prefix dcterms: . +@prefix project: . + +project:EVD-20260818-09ZEF-2 + a sd:VerificationEvidence ; + dcterms:identifier "EVD-20260818-09ZEF-2" ; + sd:repositoryPath ".spiral/evidence/EVD-20260818-09ZEF-2.md" ; + sd:status sd:Active ; + sd:verifies [ + a sd:ArtifactReference ; + sd:artifact project:IMP-20260818-09ZEF-1 ; + sd:gitCommit "569e0eaab953b6294ba1c9e04204b25f95612df4" + ] . diff --git a/.spiral/evidence/EVD-20260818-09ZEF-3.md b/.spiral/evidence/EVD-20260818-09ZEF-3.md new file mode 100644 index 0000000..f3adac4 --- /dev/null +++ b/.spiral/evidence/EVD-20260818-09ZEF-3.md @@ -0,0 +1,69 @@ +--- +id: EVD-20260818-09ZEF-3 +--- + +# Verification Evidence: Spiral Tree Validation With Submodule Core + +## Claim being verified + +The CYC-018 process update can run Spiral's new RDF validator for Git tree/prospective-integration validation after preparing a Python environment with `rdflib`, and SimplyStore's local process correction in `IMP-20260818-09ZEF-1` supports validation when `.spiral-core` is installed as a submodule. + +## Why this evidence exists + +Earlier CYC-018 evidence recorded that local validation could not run because `rdflib` was unavailable. Retrying Python setup showed that a temporary virtual environment now works, which exposed more precise validator behavior: tree validation can pass with local vocabulary, while worktree validation still includes `.spiral-core`'s own Turtle files and reports duplicate identifiers. + +## Implementation under test + +| Artifact/path/symbol | Commit | Role | +|---|---|---| +| `.spiral/implementations/IMP-20260818-09ZEF-1.*` | `89376889923eb10bc8b431cd22e422797c9eb5ca` | Process-adoption implementation including local vocabulary and workflow adjustment. | +| `.spiral/vocabulary.ttl` | `89376889923eb10bc8b431cd22e422797c9eb5ca` | Minimal local relation hierarchy for tree-based validation. | +| `.github/workflows/spiral-integration.yml` | `89376889923eb10bc8b431cd22e422797c9eb5ca` | Pull-request integration validation plus direct tree validation for merge-group commits. | + +## Evidence method + +- [x] Automated test +- [x] Property/invariant check +- [x] Static analysis +- [ ] Benchmark +- [x] Manual observation +- [ ] Integration exercise +- [ ] Other: + +## Result + +Commands run: + +```text +python3 --version +python3 -m ensurepip --version +python3 -m venv /tmp/simplystore-spiral-venv +/tmp/simplystore-spiral-venv/bin/python -m pip install -r .spiral-core/requirements.txt +PATH=/tmp/simplystore-spiral-venv/bin:$PATH python3 .spiral-core/bin/spiral-rdf.py --repo . --tree HEAD +PATH=/tmp/simplystore-spiral-venv/bin:$PATH node .spiral-core/bin/spiral.mjs validate integration --base master --head HEAD +PATH=/tmp/simplystore-spiral-venv/bin:$PATH node .spiral-core/bin/spiral.mjs validate +npm test +git diff --check +``` + +Results: + +- Python is `3.13.7`. +- `ensurepip` is available. +- `/tmp/simplystore-spiral-venv` was created successfully. +- `rdflib-7.6.0` and `pyparsing-3.3.2` installed successfully into the temporary virtual environment. +- Direct tree validation passed for `HEAD`: `ok: true`, `turtleFiles: 57`, `triples: 608`. +- Prospective integration validation passed for `master` plus `HEAD`: `validation: ok`, base `2c6d7130703e4142165f7590722bca3982f5eb04`, head `89376889923eb10bc8b431cd22e422797c9eb5ca`, tree `d15635840b6b7ef18cefe6387e2669f43ab30f5f`. +- Worktree validation still fails because it scans `.spiral-core`'s own Turtle artifacts and reports duplicate legacy identifiers such as `CTX-001`, `CYC-001`, `DES-001`, `EVD-001`, `IMP-001`, `REQ-001`, `SRC-001`, and `UND-001`. +- `npm test` passed: 16/16 startup durability tests. +- `git diff --check` passed. + +## Failure cases / limits + +- The temporary virtual environment lives under `/tmp` and is not durable project setup. +- `node .spiral-core/bin/spiral.mjs validate` is not currently suitable in this submodule-consuming repository until upstream excludes nested process repositories or accepts an explicit project graph root. +- The GitHub workflow is still only effective as a merge gate if repository hosting settings require it. + +## Evidence quality + +This evidence supersedes the earlier local-Python uncertainty with a narrower finding: dependency installation can work via a temporary virtual environment, tree/prospective-integration validation passes with the local vocabulary, and the remaining issue is the upstream worktree scan behavior. diff --git a/.spiral/evidence/EVD-20260818-09ZEF-3.ttl b/.spiral/evidence/EVD-20260818-09ZEF-3.ttl new file mode 100644 index 0000000..9b02450 --- /dev/null +++ b/.spiral/evidence/EVD-20260818-09ZEF-3.ttl @@ -0,0 +1,14 @@ +@prefix sd: . +@prefix dcterms: . +@prefix project: . + +project:EVD-20260818-09ZEF-3 + a sd:VerificationEvidence ; + dcterms:identifier "EVD-20260818-09ZEF-3" ; + sd:repositoryPath ".spiral/evidence/EVD-20260818-09ZEF-3.md" ; + sd:status sd:Active ; + sd:verifies [ + a sd:ArtifactReference ; + sd:artifact project:IMP-20260818-09ZEF-1 ; + sd:gitCommit "89376889923eb10bc8b431cd22e422797c9eb5ca" + ] . diff --git a/.spiral/evidence/EVD-20260819-09ZEF-4.md b/.spiral/evidence/EVD-20260819-09ZEF-4.md new file mode 100644 index 0000000..c68d106 --- /dev/null +++ b/.spiral/evidence/EVD-20260819-09ZEF-4.md @@ -0,0 +1,65 @@ +--- +id: EVD-20260819-09ZEF-4 +--- + +# Verification Evidence: Latest Spiral Core Integration Rules + +## Claim being verified + +The later CYC-018 process update adopts `.spiral-core` commit `8d4b2c738a413abd4cccca740ce958f486e5f7af` and adjusts SimplyStore's local process surface for the new cycle-closure, branch-metadata, and explicit-convergence rules without changing SimplyStore runtime behavior. + +## Why this evidence exists + +The human asked to update `.spiral-core` again and follow any new instructions. The upstream process changed after the previous CYC-018 verification, so SimplyStore needed fresh evidence for the new effective process rules. + +## Implementation under test + +| Artifact/path/symbol | Commit | Role | +|---|---|---| +| `.spiral/implementations/IMP-20260818-09ZEF-1.*` | `725a861ccb577fa5918202d1f486b2e19d02c896` | Process-adoption implementation updated for the latest core commit and distributed integration rules. | +| `.spiral-core` | `725a861ccb577fa5918202d1f486b2e19d02c896` | Submodule pointer to Spiral core `8d4b2c738a413abd4cccca740ce958f486e5f7af`. | +| `.github/workflows/spiral-integration.yml` | `725a861ccb577fa5918202d1f486b2e19d02c896` | Pull-request validation now passes base/head branch metadata. | +| `.spiral/vocabulary.ttl` | `725a861ccb577fa5918202d1f486b2e19d02c896` | Local tree-validation vocabulary now includes historical relation subproperties. | + +## Evidence method + +- [x] Automated test +- [x] Property/invariant check +- [x] Static analysis +- [ ] Benchmark +- [x] Manual observation +- [x] Integration exercise +- [ ] Other: + +## Result + +Commands run: + +```text +git -C .spiral-core fetch git@github.com:muze-labs/spiral-developer.git main +git -C .spiral-core checkout FETCH_HEAD +git diff --cached --check +PATH=/tmp/simplystore-spiral-venv/bin:$PATH python3 .spiral-core/bin/spiral-rdf.py --repo . --tree bc08d189061011d5300e42963ca3d56470cea548 +PATH=/tmp/simplystore-spiral-venv/bin:$PATH python3 .spiral-core/bin/spiral-rdf.py --repo . --tree HEAD +PATH=/tmp/simplystore-spiral-venv/bin:$PATH node .spiral-core/bin/spiral.mjs validate integration --base master --head HEAD --base-branch master --head-branch spiral/CYC-018-spiral-core-update +PATH=/tmp/simplystore-spiral-venv/bin:$PATH node .spiral-core/bin/spiral.mjs validate +``` + +Results: + +- HTTPS `git fetch` still could not authenticate non-interactively, but SSH fetch succeeded. +- `.spiral-core` moved from `b24a5e8e301437561f2ed7e60486014cebae12c6` to upstream `8d4b2c738a413abd4cccca740ce958f486e5f7af`. +- Staged tree validation passed before commit: `ok: true`, tree `bc08d189061011d5300e42963ca3d56470cea548`, `turtleFiles: 58`, `triples: 618`. +- Direct tree validation passed after commit: `ok: true`, tree `HEAD`, `turtleFiles: 58`, `triples: 618`. +- Branch-aware prospective integration validation against `master` failed with `open-cycle-integration` because CYC-018 is still `sd:Active`. This is the intended new guard: Active cycle branches must not merge into accepted history before human acceptance is recorded. +- Plain worktree validation still fails because it scans `.spiral-core`'s own Turtle artifacts and reports duplicate legacy identifiers such as `CTX-001`, `CYC-001`, `DES-001`, `EVD-001`, `IMP-001`, `REQ-001`, `SRC-001`, and `UND-001`. + +## Failure cases / limits + +- The GitHub workflow's merge-group path still uses direct tree validation because plain worktree validation remains unsuitable for this submodule-consuming repository. +- The process update cannot pass branch-aware integration validation until CYC-018 is accepted and its cycle record is updated to `sd:Accepted`. +- Repository branch protection / required-check settings remain outside the Git tree. + +## Evidence quality + +This evidence mechanically verifies the current committed graph snapshot and confirms that the newly adopted integration rule blocks outward integration of the still-open cycle. It also preserves the remaining submodule worktree-validation limitation as an explicit process/tooling gap rather than hiding it. diff --git a/.spiral/evidence/EVD-20260819-09ZEF-4.ttl b/.spiral/evidence/EVD-20260819-09ZEF-4.ttl new file mode 100644 index 0000000..67ce358 --- /dev/null +++ b/.spiral/evidence/EVD-20260819-09ZEF-4.ttl @@ -0,0 +1,14 @@ +@prefix sd: . +@prefix dcterms: . +@prefix project: . + +project:EVD-20260819-09ZEF-4 + a sd:VerificationEvidence ; + dcterms:identifier "EVD-20260819-09ZEF-4" ; + sd:repositoryPath ".spiral/evidence/EVD-20260819-09ZEF-4.md" ; + sd:status sd:Active ; + sd:verifies [ + a sd:ArtifactReference ; + sd:artifact project:IMP-20260818-09ZEF-1 ; + sd:gitCommit "725a861ccb577fa5918202d1f486b2e19d02c896" + ] . diff --git a/.spiral/implementations/IMP-20260818-09ZEF-1.md b/.spiral/implementations/IMP-20260818-09ZEF-1.md new file mode 100644 index 0000000..6bb9d8f --- /dev/null +++ b/.spiral/implementations/IMP-20260818-09ZEF-1.md @@ -0,0 +1,65 @@ +--- +id: IMP-20260818-09ZEF-1 +--- + +# Implementation: Spiral Core Distributed Development Adoption + +## Scope + +Process-only update that refreshes `.spiral-core` and adopts the upstream distributed-development and integration-validation guidance in SimplyStore's local process surface. + +## Observable behavior + +- `.spiral-core` points at upstream commit `8d4b2c738a413abd4cccca740ce958f486e5f7af`. +- New Spiral artifacts after CYC-018 should use distributed-safe IDs allocated by `node .spiral-core/bin/spiral.mjs allocate `. +- Legacy sequential IDs remain valid historical artifacts and are not renamed. +- This checkout has initialized worktree-local allocator state with namespace `09ZEF`. +- Local instructions now call out `docs/distributed-development.md`. +- Local instructions and project context now require pre-merge Spiral integration validation against the current `master` target or the hosting platform's exact prospective merged result. +- A GitHub Actions adapter exists at `.github/workflows/spiral-integration.yml` for pull requests and merge groups. +- Pull-request integration validation now passes base/head branch metadata so the updated Spiral core can enforce cycle closure and branch/cycle correspondence. +- Local process guidance now records that Active cycle branches do not merge outward and that parallel material revisions of the same governed artifact require explicit convergence lineage with `sd:transforms`. +- Project context now records the authoritative integration branch, integration boundary, validation command, and known hosting/validator dependency gaps. +- The old repository-local `scripts/validate-spiral-provenance.mjs` parser accepts distributed artifact IDs so it reaches its known CYC-016-specific branch check rather than failing on new valid IDs. +- `.spiral/vocabulary.ttl` provides the minimal local relation hierarchy needed for tree-based validation when `.spiral-core` is present only as a submodule gitlink. +- The GitHub merge-group workflow validates the merge-group commit tree directly, avoiding the current worktree validator issue where `.spiral-core`'s own Turtle files are included. + +## Repository locations + +| Path / symbol | Role | +|---|---| +| `.spiral-core` | Git submodule pointer for Spiral Developer process. | +| `AGENTS.md` | Local agent operating instructions for SimplyStore. | +| `.spiral/project-context.md` | Durable local process/project memory. | +| `.github/workflows/spiral-integration.yml` | GitHub adapter for prospective Spiral integration validation. | +| `.spiral/vocabulary.ttl` | Minimal local relation hierarchy for tree-based Spiral validation. | +| `scripts/validate-spiral-provenance.mjs` | Legacy CYC-016 validator made tolerant of distributed artifact IDs. | + +## Effective provenance + +This implementation realizes CYC-018 and continues the process-adoption lineage from `IMP-008`. + +This revision also repairs the first implementation version's accidental incompatibility with distributed artifact IDs in the old CYC-016-specific validator, adds the local vocabulary/merge-group adjustment required for the new validator to work against Git tree snapshots in a submodule-consuming repository, and adopts the later upstream cycle-closure/explicit-convergence guidance. + +## Important implementation decisions + +- No SimplyStore product/runtime code changed. +- CYC-018 keeps its legacy sequential ID because it was opened before the updated distributed-ID process was adopted locally. +- The GitHub workflow installs `rdflib` in CI rather than committing a local virtual environment or forcing system Python changes. +- Branch protection and required-check settings are not stored in the repository and remain an external hosting configuration task. +- The old repository-local validator is not promoted back to the primary validation mechanism; the Spiral core CLI is the current process target. +- Local worktree validation remains blocked by the upstream validator's recursive scan through the `.spiral-core` submodule; tree-based validation passes with the local vocabulary. +- The merge-group workflow keeps direct tree validation for the exact queued commit because the local submodule installation still makes plain worktree validation unsuitable in this consuming repository. + +## New dependencies / capabilities / permissions + +- The adopted Spiral validator requires Python `rdflib>=7,<8` from `.spiral-core/requirements.txt`. +- Local validation was not made to install globally because this OS blocks user-site pip installs and lacks `python3-venv`, `uv`, and `pipx`. +- CI installs the validator dependency explicitly. + +## Known limits + +- Local validation requires a Python environment with `rdflib`; a temporary virtual environment under `/tmp` has worked in this environment. +- The GitHub workflow is only effective as a merge gate after repository hosting settings require it. +- Existing repository-local `scripts/validate-spiral-provenance.mjs` remains CYC-016-specific. +- `node .spiral-core/bin/spiral.mjs validate` remains unsuitable locally until upstream excludes nested submodule Turtle files or gains a project-root selector. diff --git a/.spiral/implementations/IMP-20260818-09ZEF-1.ttl b/.spiral/implementations/IMP-20260818-09ZEF-1.ttl new file mode 100644 index 0000000..caa2bc6 --- /dev/null +++ b/.spiral/implementations/IMP-20260818-09ZEF-1.ttl @@ -0,0 +1,26 @@ +@prefix sd: . +@prefix dcterms: . +@prefix project: . + +project:IMP-20260818-09ZEF-1 + a sd:Implementation ; + dcterms:identifier "IMP-20260818-09ZEF-1" ; + sd:repositoryPath ".spiral/implementations/IMP-20260818-09ZEF-1.md" ; + sd:status sd:Active ; + sd:implementationLocation ".spiral-core" ; + sd:implementationLocation "AGENTS.md" ; + sd:implementationLocation ".spiral/project-context.md" ; + sd:implementationLocation ".github/workflows/spiral-integration.yml" ; + sd:implementationLocation ".spiral/vocabulary.ttl" ; + sd:implementationLocation "scripts/validate-spiral-provenance.mjs" ; + sd:transforms [ + a sd:ArtifactReference ; + sd:artifact project:IMP-20260818-09ZEF-1 ; + sd:gitCommit "89376889923eb10bc8b431cd22e422797c9eb5ca" + ] ; + sd:changeCausedBy [ + a sd:ArtifactReference ; + sd:artifact project:CYC-018 ; + sd:gitCommit "4cefd007da682ce8ef46ccfc4852882fb34e2003" + ] ; + sd:implementationChangeKind sd:SemanticChange . diff --git a/.spiral/project-context.md b/.spiral/project-context.md index 7488962..fbbc043 100644 --- a/.spiral/project-context.md +++ b/.spiral/project-context.md @@ -16,9 +16,9 @@ Repository/baseline: `https://github.com/simplyedit/simplystore`, local authorit Project causal-graph namespace: `https://github.com/simplyedit/simplystore/spiral#` -Spiral core source: `.spiral-core/`, git submodule for `https://github.com/muze-labs/spiral-developer.git`, currently checked out at `3111b784531e327da75801f5ba8b61e891341d5f`. +Spiral core source: `.spiral-core/`, git submodule for `https://github.com/muze-labs/spiral-developer.git`, currently checked out at `8d4b2c738a413abd4cccca740ce958f486e5f7af`. -Current active Spiral cycle: none. Latest accepted Spiral cycle: `.spiral/cycles/CYC-017.md` (`Command And Load Worker Timeout Semantics`). +Current active Spiral cycle: `.spiral/cycles/CYC-018.md` (`Spiral Core Process Update`). Latest accepted Spiral cycle: `.spiral/cycles/CYC-017.md` (`Command And Load Worker Timeout Semantics`). ## Intake State @@ -38,9 +38,38 @@ Human-confirmed complete on: 2026-08-17 | Knowledge gaps / affinity needs | Covered | Areas needing affinity / human guidance table | | Relevant future direction | Covered | Current direction and later possibilities sections | | Risk-discovery / metric-profile disposition | Covered | Intake risk-discovery and metric-profile tables | +| Integration context / pre-merge Spiral validation | Covered with unknowns | Spiral integration context section; GitHub check added, required-branch protection/merge queue status unknown | Future work should reopen intake as `Stale` if SimplyStore's audience, production-readiness target, downstream commitments, or API/disk-format compatibility expectations materially change. +## Spiral Integration Context + +Authoritative integration branch/ref: `master`. + +Review/integration boundary: normal pull request or equivalent human review, followed by a history-preserving merge commit. Squash and rebase merges are not appropriate for Spiral cycle history because semantic commit hashes are causal evidence. + +Pre-merge Spiral validation boundary: before integrating an accepted cycle branch, validate the actual candidate against the current `master` target with: + +```text +node .spiral-core/bin/spiral.mjs validate integration --base master --head --base-branch master --head-branch +``` + +or use a hosting/CI check that validates the exact prospective merged or merge-queue result with branch metadata where available. Active cycle branches must not merge outward; human acceptance should be recorded as `sd:Accepted` before proposing integration. When accepted `master` work is merged into an Active cycle branch, any merge version that combines parallel material revisions of the same governed artifact must explicitly preserve both immediate predecessor lineages with `sd:transforms`. `.github/workflows/spiral-integration.yml` was added in CYC-018 as the repository adapter for pull requests and GitHub merge groups. Repository hosting settings still need to make the check required if it is meant to block merges. + +Local validator dependency: the current Spiral CLI requires Python `rdflib` from `.spiral-core/requirements.txt`. This local environment can run validation with a temporary virtual environment whose `bin` directory is first on `PATH`. CI installs the dependency explicitly. + +Local validator limitation: `node .spiral-core/bin/spiral.mjs validate` currently scans the `.spiral-core` submodule's own Turtle files and reports duplicate legacy artifact identifiers. Use prospective tree/integration validation for SimplyStore until upstream validator behavior excludes nested process repositories. + +Local vocabulary: `.spiral/vocabulary.ttl` carries the minimal Spiral relation hierarchy needed for tree-based validation of this consuming repository. Without it, integration validation sees the `.spiral-core` submodule only as a Git gitlink and cannot derive `sd:causalReference` subproperties from the core ontology. + +Artifact allocation: new Spiral artifacts after CYC-018 should use distributed-safe IDs allocated by: + +```text +node .spiral-core/bin/spiral.mjs allocate +``` + +Legacy sequential artifact IDs remain valid and should not be renamed. CYC-018 itself was opened with the legacy sequential ID before this core update was adopted. This checkout has worktree-local allocator namespace `09ZEF` under `.git/spiral`; that namespace is private local allocation state, not shared project content and not actor identity. + ## Intended Users Primary audience: developers using or extending SimplyStore. @@ -141,14 +170,14 @@ This is not yet a claim that SimplyStore is production-safe for all workloads. I | Culture/profile | Version/source | Applicability here | Why active here | Local deviations | |---|---|---|---|---| -| `CUL-MUZE-001` — Muze Engineering Culture | `.spiral-core/cultures/muze-engineering.md` at submodule commit `3111b784531e327da75801f5ba8b61e891341d5f` | Broad SimplyStore engineering choices | SimplyStore is a Muze-owned software project; principles such as simplicity, correctable boundaries, inspectability, and replaceability match the durability direction | Apply as defeasible preference, not hidden requirement | -| `CUL-MUZE-LIB-001` — Muze Library Stewardship Culture | `.spiral-core/cultures/muze-library-stewardship.md` at submodule commit `3111b784531e327da75801f5ba8b61e891341d5f` | Reusable library/package stewardship | SimplyStore is an `@muze-nl` reusable Node package moving toward production readiness | Apply only where library stewardship concerns fit; do not let package maturity override evidence | +| `CUL-MUZE-001` — Muze Engineering Culture | `.spiral-core/cultures/muze-engineering.md` at submodule commit `8d4b2c738a413abd4cccca740ce958f486e5f7af` | Broad SimplyStore engineering choices | SimplyStore is a Muze-owned software project; principles such as simplicity, correctable boundaries, inspectability, and replaceability match the durability direction | Apply as defeasible preference, not hidden requirement | +| `CUL-MUZE-LIB-001` — Muze Library Stewardship Culture | `.spiral-core/cultures/muze-library-stewardship.md` at submodule commit `8d4b2c738a413abd4cccca740ce958f486e5f7af` | Reusable library/package stewardship | SimplyStore is an `@muze-nl` reusable Node package moving toward production readiness | Apply only where library stewardship concerns fit; do not let package maturity override evidence | ## Active Warning Profiles | Warning profile | Version/source | Applicability here | Why active here | Local deviations | |---|---|---|---|---| -| `WPF-HUMAN-001` — Human Impact and Epistemic Warning Profile | `.spiral-core/warning-profiles/human-impact-and-epistemic.md` at submodule commit `3111b784531e327da75801f5ba8b61e891341d5f` | Consequential design, durability, evidence, access, and confidence claims | Durability work depends on evidence quality and avoiding overclaiming production readiness | Apply significance gate; surface concise operational warnings only when material | +| `WPF-HUMAN-001` — Human Impact and Epistemic Warning Profile | `.spiral-core/warning-profiles/human-impact-and-epistemic.md` at submodule commit `8d4b2c738a413abd4cccca740ce958f486e5f7af` | Consequential design, durability, evidence, access, and confidence claims | Durability work depends on evidence quality and avoiding overclaiming production readiness | Apply significance gate; surface concise operational warnings only when material | ## Intake Risk-Discovery Profiles @@ -199,7 +228,8 @@ This is not yet a claim that SimplyStore is production-safe for all workloads. I | Corrupted or altered OD-JSONTag durable data can undermine recovery confidence | Monitor | Human direction before CYC-012, `DES-001`, `IMP-006`, `EVD-011` | Malformed/truncated OD-JSONTag record framing in base and committed changeset files now fails explicitly; malformed-framing uncommitted changesets are ignored; full syntax validation and well-formed tampering need future integrity metadata | | Retried command IDs can mislead clients or enqueue duplicate transitions | Monitor | Original durability order in `SRC-001`, `DES-001`, `IMP-007`, `EVD-012` | Retries during active/done/recovered/unsafe states now return the current command status and do not enqueue duplicate transitions in the tested paths; duplicate payload mismatch semantics remain future API work | | Legacy index hooks have implicit mutation and external-write semantics | Investigate | `DES-002`, CYC-015 characterization | Current `index.update()` can mutate canonical state, blocks commit on failure, and can leave external derived files behind when it writes before throwing | -| Command timeouts can leave command progress ambiguous without a process crash | Defer | Human risk assessment question on 2026-08-18, `DES-001` durability invariants | Current evidence covers process crashes and slow active-command retry behavior, but not a command worker or command handler that times out while the server process survives. Assess after the current cycle: terminal status, replay behavior, client timeout semantics, and restart-loop risk need explicit classification. | +| Command and load worker timeouts can leave progress ambiguous without a process crash | Monitor | `DES-003`, `IMP-011`, `EVD-018` | CYC-017 added parent-side command/load worker timeouts. Hanging commands become terminal `unsafe`, duplicate command IDs return that status, later queued commands can commit, and hanging load fails startup explicitly. Timeout defaults and documentation remain future polish. | +| Spiral integration validation is not yet known to be required by repository hosting | Monitor | CYC-018 process update | `.github/workflows/spiral-integration.yml` exists after CYC-018, but branch protection/required-check settings are outside the repository tree and remain unknown. | ## Reliable Feedback / Reality Sources diff --git a/.spiral/vocabulary.ttl b/.spiral/vocabulary.ttl new file mode 100644 index 0000000..5b7ad6c --- /dev/null +++ b/.spiral/vocabulary.ttl @@ -0,0 +1,18 @@ +@prefix sd: . +@prefix rdfs: . + +sd:derivedFrom rdfs:subPropertyOf sd:causalReference . +sd:interprets rdfs:subPropertyOf sd:causalReference . +sd:satisfies rdfs:subPropertyOf sd:causalReference . +sd:supports rdfs:subPropertyOf sd:causalReference . +sd:constrainedBy rdfs:subPropertyOf sd:causalReference . +sd:shapedBy rdfs:subPropertyOf sd:causalReference . +sd:adoptsCulture rdfs:subPropertyOf sd:causalReference . +sd:adoptsWarningProfile rdfs:subPropertyOf sd:causalReference . +sd:implements rdfs:subPropertyOf sd:causalReference . +sd:verifies rdfs:subPropertyOf sd:causalReference . +sd:accepts rdfs:subPropertyOf sd:causalReference . +sd:observes rdfs:subPropertyOf sd:causalReference . +sd:supersedes rdfs:subPropertyOf sd:causalReference . +sd:transforms rdfs:subPropertyOf sd:historicalReference . +sd:changeCausedBy rdfs:subPropertyOf sd:historicalReference . diff --git a/AGENTS.md b/AGENTS.md index cc5b655..bed8aa4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,6 +21,9 @@ For initial or reframed brownfield work, also read: - `.spiral-core/prompts/repository-bootstrap.md` - `.spiral-core/docs/brownfield-intake.md` - `.spiral-core/prompts/brownfield-intake.md` +- `.spiral-core/docs/distributed-development.md` + +The currently adopted `.spiral-core` version is recorded in `.spiral/project-context.md`. ## Local Adoption State @@ -46,7 +49,13 @@ Do not create Spiral artifacts merely to populate folders. Add `.spiral/` artifa - Treat `master` as the authoritative branch unless the human states otherwise. - For ordinary repository-changing Spiral cycle work, create one dedicated branch from the authoritative branch, normally `spiral/CYC-###-short-goal`. +- For new Spiral artifacts after CYC-018, use distributed-safe IDs allocated by `node .spiral-core/bin/spiral.mjs allocate ` instead of scanning for the next legacy number. Existing `SRC-001` / `CYC-017` style IDs remain valid historical artifacts and must not be renamed. +- Before allocating a new artifact ID, check `node .spiral-core/bin/spiral.mjs status`. This checkout has worktree-local allocator state under `.git/spiral`; other clones/worktrees will have their own namespace. - Preserve Git history as evidence. Do not amend, rebase, squash, reset, or force-push causal cycle history. +- An Active cycle branch must not merge into `master` or another Active cycle branch. Record human acceptance by changing the cycle to `sd:Accepted` before proposing integration. +- Before proposing or merging accepted cycle work, run `node .spiral-core/bin/spiral.mjs validate integration --base --head --base-branch master --head-branch `, or rely on a hosting check that validates the exact prospective merged result with branch metadata. +- When accepted `master` work is merged into an Active cycle branch, prefer `git merge --no-commit master` if governed artifacts may have changed on both sides. If both parent histories materially changed the same governed artifact, reconcile the merge version and record both immediate predecessor versions with `sd:transforms`. +- The Spiral validator requires Python `rdflib` from `.spiral-core/requirements.txt`. Local worktree validation currently sees `.spiral-core`'s own Turtle files because the process is installed as a submodule, so prefer tree/prospective-integration validation until upstream validator behavior excludes nested process repositories. - Treat planning, evaluation, and ambiguous human suggestions as discourse until there is an explicit commitment. Do not turn tentative comments into scope or architecture merely because they are implementable. - Treat human confirmation of a sufficiently explicit cycle goal as the commitment boundary for execution within that goal and its non-goals. - Surface material ambiguity, contradiction, unsupported premise, or alternative framing before commitment when resolving it differently would plausibly change what is built, tested, accepted, or treated as the problem. diff --git a/scripts/validate-spiral-provenance.mjs b/scripts/validate-spiral-provenance.mjs index 236a28c..e2c8c8e 100644 --- a/scripts/validate-spiral-provenance.mjs +++ b/scripts/validate-spiral-provenance.mjs @@ -93,7 +93,7 @@ function parseTurtleSubset(text, file) { throw new Error(`${file}: expected final .`) } - const subjectMatch = text.match(/project:([A-Za-z]+-\d+)\s+([\s\S]*)\.\s*$/) + const subjectMatch = text.match(/project:([A-Za-z][A-Za-z0-9-]*)\s+([\s\S]*)\.\s*$/) if (!subjectMatch) { throw new Error(`${file}: expected one project subject block`) } @@ -109,7 +109,7 @@ function parseTurtleSubset(text, file) { } const references = [] - const refRegex = /sd:([A-Za-z]+)\s+\[\s*a\s+sd:ArtifactReference\s*;\s*sd:artifact\s+project:([A-Za-z]+-\d+)\s*;\s*sd:gitCommit\s+"([0-9a-f]+)"(?:\s*;\s*sd:fragment\s+"([^"]+)")?\s*\]/g + const refRegex = /sd:([A-Za-z]+)\s+\[\s*a\s+sd:ArtifactReference\s*;\s*sd:artifact\s+project:([A-Za-z][A-Za-z0-9-]*)\s*;\s*sd:gitCommit\s+"([0-9a-f]+)"(?:\s*;\s*sd:fragment\s+"([^"]+)")?\s*\]/g let match while ((match = refRegex.exec(body)) !== null) { references.push({