diff --git a/.github/AGENTS.md b/.github/AGENTS.md new file mode 100644 index 00000000..2beffb58 --- /dev/null +++ b/.github/AGENTS.md @@ -0,0 +1,25 @@ +# CI and Publication Guide + +## CI matrix + +The main workflow covers C++11, C++14, and C++17 on Linux, Windows, and +macOS, plus install, vcpkg, and multiarch pkg-config consumers. Public-header +changes must preserve all matrix jobs and both NTP configurations. + +## Documentation publication + +`publish.yaml` validates pull requests without deploying. A push to `main` +publishes development documentation using the CMake version with a `-dev` +suffix. A matching `v*` tag publishes release documentation. The tag version +must equal the CMake project version. + +Keep the preconditions, substitution, and postcondition checks together. Do +not commit generated `VERSION_PLACEHOLDER` substitutions or a populated +`PROJECT_NUMBER` to source files. + +## vcpkg validation + +The PR vcpkg job may pin a temporary checkout revision dynamically so that CI +tests the exact change under review. The checked-in overlay remains the +immutable release source of truth and must have a matching `REF` and SHA512. + diff --git a/AGENTS.md b/AGENTS.md index 6471f18a..31357d4e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,6 +9,11 @@ Use the repository guidance in this order: 5. `docs/singleton-storage-guidelines.md` 6. `agents/singleton-storage-guidelines.md` +For directory-specific contracts, read the owning module guide from the +[agent documentation index](agents/README.md) before editing. The index covers +public headers, tests, documentation, CI/publication, packaging, and MQL +sources. Keep this root file limited to repository-wide rules and routing. + Optional local settings: - If `agents/local-machine-settings.json` exists, read it after the tracked repository guidance. @@ -70,7 +75,7 @@ Use the following order for repository changes and reviews: 3. Build with CMake and the `MinGW Makefiles` generator. Keep build and test directories under `tmp/agent-work/`. 4. Run CTest in both Debug and Release configurations. Runtime test checks must remain active in Release builds. 5. Check C++11, C++14, and C++17 compatibility, installation consumers, and ODR tests when public headers change. -6. Treat MQL5 scripts as manual tests unless a MetaEditor compiler is available. Manual scripts report an aggregate pass/fail result. +6. Treat MQL4 and MQL5 scripts as manual tests unless a MetaEditor compiler is available. Manual scripts report an aggregate pass/fail result. 7. Preserve convenient public aliases. Short or alternative names are not legacy merely because a canonical equivalent exists. Classify an API as legacy only when it has been historically renamed or superseded, or when a deliberate replacement is introduced. When replacing a useful short alias, provide an equally practical preferred alias. Move a confirmed legacy alias to `legacy_aliases.hpp` and make it available only through `TIME_SHIELD_ENABLE_LEGACY_ALIASES`. 8. Keep documentation source templates version-neutral. Do not commit generated documentation version substitutions; publish.yaml injects the effective version diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c5cc4d5..fd1987bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. -## [v2.0.0] - Unreleased +## [v2.0.0] - 2026-09-12 - Added `dse`, `dse_ms`, `dse_to_ts`, and `dse_to_ts_ms` convenience aliases for days-since-epoch conversions. - Corrected the default return type of `unix_day_to_ts_ms` to the millisecond timestamp type. - Added `ZonedClock` with reusable named-zone and fixed-offset local-time helpers, including explicit resolution of ambiguous and nonexistent local times. diff --git a/MQL4/AGENTS.md b/MQL4/AGENTS.md new file mode 100644 index 00000000..7c17fc24 --- /dev/null +++ b/MQL4/AGENTS.md @@ -0,0 +1,9 @@ +# MQL4 Agent Guide + +Keep MQL4 include guards project-prefixed and path-derived. Preserve the public +facade contract and keep examples aligned with the C++ naming and version +policy where the APIs correspond. + +MetaEditor is not part of the standard local toolchain. Treat MQL4 scripts as +manual checks and report an aggregate result when running them. + diff --git a/MQL5/AGENTS.md b/MQL5/AGENTS.md new file mode 100644 index 00000000..fb0468e3 --- /dev/null +++ b/MQL5/AGENTS.md @@ -0,0 +1,9 @@ +# MQL5 Agent Guide + +Keep MQL5 include guards project-prefixed and path-derived. Preserve the +MQL5/C++ timestamp bounds and shared constant contracts. Keep compatibility +aliases intentional and document any opt-in legacy behavior. + +MetaEditor is not part of the standard local toolchain. Treat MQL5 scripts as +manual checks and report an aggregate result when running them. + diff --git a/agents/README.md b/agents/README.md new file mode 100644 index 00000000..3f8edea7 --- /dev/null +++ b/agents/README.md @@ -0,0 +1,19 @@ +# Time Shield Agent Documentation + +`AGENTS.md` is the repository-wide routing document. Read it first, then read +the module guide that owns the files being changed. + +| Area | Guide | Read when | +| --- | --- | --- | +| Public C++ headers | [`include/AGENTS.md`](../include/AGENTS.md) | Changing headers, aliases, includes, guards, or domain boundaries | +| Tests and consumers | [`tests/AGENTS.md`](../tests/AGENTS.md) | Adding tests or changing CMake test targets and install consumers | +| Documentation and site | [`docs/AGENTS.md`](../docs/AGENTS.md) | Changing Doxygen, Markdown, site styling, or publication output | +| CI and publication | [`../.github/AGENTS.md`](../.github/AGENTS.md) | Changing workflows, release checks, or generated documentation publication | +| vcpkg packaging | [`../vcpkg-overlay/AGENTS.md`](../vcpkg-overlay/AGENTS.md) | Changing the overlay port or release source pin | +| MQL4 | [`../MQL4/AGENTS.md`](../MQL4/AGENTS.md) | Changing MQL4 headers, facades, or scripts | +| MQL5 | [`../MQL5/AGENTS.md`](../MQL5/AGENTS.md) | Changing MQL5 headers, facades, or scripts | + +The reusable ownership and singleton policies remain in the linked developer +and agent guides listed by the root document. Keep module guides focused on +contracts that are specific to their directory. + diff --git a/docs/AGENTS.md b/docs/AGENTS.md new file mode 100644 index 00000000..08a1cdc6 --- /dev/null +++ b/docs/AGENTS.md @@ -0,0 +1,27 @@ +# Documentation Agent Guide + +## Source and generated output + +Markdown files and `Doxyfile` are documentation sources. Keep them +version-neutral: `docs/mainpage.md` uses `VERSION_PLACEHOLDER` and `Doxyfile` +keeps `PROJECT_NUMBER` empty. Publication workflows inject the effective +version into a temporary working copy before running Doxygen. + +Do not commit generated substitutions or generated `docs/html` changes as part +of a source documentation edit. Keep local previews under +`tmp/agent-work/`. + +## Doxygen and site contract + +- Keep public include examples on canonical domain paths. +- Keep archived assets excluded from generated navigation and publication. +- Preserve the Doxygen Awesome layout, responsive sidebar, search area, and + light/dark theme toggle. +- Validate both desktop and mobile layout when changing site CSS or JavaScript. +- Keep comments and Doxygen text in English, declarative present tense, and + consistent with the public API contract. + +The publish workflow validates Doxygen generation and the Playwright smoke +tests. Reproduce those checks locally when practical rather than inspecting +generated HTML alone. + diff --git a/include/AGENTS.md b/include/AGENTS.md new file mode 100644 index 00000000..27806955 --- /dev/null +++ b/include/AGENTS.md @@ -0,0 +1,50 @@ +# Public Header Guide + +## Canonical layout + +Public C++ headers use eight root umbrellas and eight owning domains: + +```text +include/time_shield/ +├── astronomy.hpp ├── astronomy/ +├── conversions.hpp ├── conversions/ +├── core.hpp ├── core/ +├── date_time.hpp ├── datetime/ +├── ntp.hpp ├── ntp/ +├── text.hpp ├── text/ +├── timers.hpp ├── timers/ +└── timezone.hpp └── timezone/ +``` + +`include/time_shield.hpp` is the full-library entrypoint. Root-level selective +headers outside this umbrella set are not part of the public layout. Do not +add forwarding headers or recreate removed root directories. + +## Include policy + +- Use a domain umbrella for a cross-domain dependency. +- Use a local leaf include only within the owning domain. +- Keep the domain dependency graph acyclic; lower-level domains do not include + higher-level domains. +- Do not use `../` includes. +- Keep `detail/` headers inside their owning domain. Tests may include them as + white-box implementation tests. +- Keep optional NTP dependencies behind `TIME_SHIELD_ENABLE_NTP_CLIENT`. + +The CMake architecture check is the executable contract for this policy. Run +`cmake -DTIME_SHIELD_SOURCE_DIR= -P cmake/check_header_include_policy.cmake` +after changing the layout or an include. + +## Header implementation and guards + +Follow `docs/header-implementation-guidelines.md` and +`agents/header-implementation-guidelines.md` for `.hpp`, `.ipp`, and `.tpp` +ownership. Every project-owned header starts with `#pragma once` and a +project-prefixed, path-derived non-reserved guard. MQL headers use the MQL +guard prefix described in the root guide. + +Preserve the distinction between canonical, convenience, and opt-in legacy +APIs. A short name is not legacy merely because a longer canonical name exists. +Only historically superseded aliases belong in `legacy_aliases.hpp`, guarded by +`TIME_SHIELD_ENABLE_LEGACY_ALIASES`. + diff --git a/tests/AGENTS.md b/tests/AGENTS.md new file mode 100644 index 00000000..069d7c4e --- /dev/null +++ b/tests/AGENTS.md @@ -0,0 +1,38 @@ +# Test Guide + +## Build and run + +Use the repository CMake generator and keep build trees under +`tmp/agent-work/`: + +```powershell +cmake -S . -B tmp/agent-work/build-debug -G "MinGW Makefiles" ` + -DTIME_SHIELD_CPP_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug +cmake --build tmp/agent-work/build-debug +ctest --test-dir tmp/agent-work/build-debug --output-on-failure +``` + +Repeat with a separate Release tree. Release tests must keep runtime checks +active; use `TIME_SHIELD_TEST_CHECK(...)` from `test_assert.hpp`, never +`assert(...)`. + +Public-header changes require checks for C++11, C++14, and C++17, Debug and +Release builds, ODR targets, and installed consumers. When relevant, test both +`TIME_SHIELD_ENABLE_NTP_CLIENT=ON` and `OFF`. + +## Test contracts + +- Include public APIs through their canonical root or domain paths. +- Use `header_smoke/` for standalone umbrella compilation and include-policy + coverage. +- Use `install_consumer/`, `pkg_config_consumer/`, and `vcpkg_consumer/` to + validate installed package contracts. +- Direct `detail/` includes are allowed only for white-box tests of the owning + domain. +- MQL scripts are manual tests unless MetaEditor is available; report one + aggregate pass/fail result. + +When adding a test source, confirm that the existing CMake glob or explicit +target includes it, and update the expected test count in release or PR +documentation when that count is quoted. + diff --git a/vcpkg-overlay/AGENTS.md b/vcpkg-overlay/AGENTS.md new file mode 100644 index 00000000..797b44b0 --- /dev/null +++ b/vcpkg-overlay/AGENTS.md @@ -0,0 +1,15 @@ +# vcpkg Overlay Guide + +The checked-in port is the reproducible package definition for a released +Time Shield version. Keep its manifest version, `portfile.cmake` source `REF`, +and archive `SHA512` consistent. + +Before a release tag, pin the overlay to an immutable commit that contains the +release source and verify the GitHub archive hash. After the tag exists, an +upstream vcpkg port may switch to `REF vX.Y.Z` with the hash of that tag +archive. + +The CI workflow may rewrite the overlay temporarily to the checked-out PR +revision. That temporary behavior must not be copied into the tracked +`portfile.cmake`. + diff --git a/vcpkg-overlay/ports/time-shield-cpp/portfile.cmake b/vcpkg-overlay/ports/time-shield-cpp/portfile.cmake index 31f02d9d..98ef5ffd 100644 --- a/vcpkg-overlay/ports/time-shield-cpp/portfile.cmake +++ b/vcpkg-overlay/ports/time-shield-cpp/portfile.cmake @@ -1,8 +1,8 @@ vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO LimiNode/time-shield-cpp - REF 231bb8f484774015dbd1219785ac85806e3b1d8a - SHA512 4c2f0aac6bd695cf6f648fc20a2e921705427260ac64562e075dd277c01df8f820f3c01505c1c054aec096133dbf85a7eddf4e49e4ca8c5fa5999ce2606c0a45 + REF 398b9a6c035d4c3e65bb565082252e6445355e03 + SHA512 5fc7edd650c4d0afc1e275c223744256a698b4381a0117b42f25e601bc9b051562bae59d400cacc6ebfa1d8424365fdd909cf5c4ac0520b7ba9673ef8985005e HEAD_REF main ) @@ -15,11 +15,6 @@ vcpkg_cmake_configure( vcpkg_cmake_install() -file(REMOVE_RECURSE - "${CURRENT_PACKAGES_DIR}/debug/include" - "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig" -) - vcpkg_cmake_config_fixup( PACKAGE_NAME TimeShield CONFIG_PATH lib/cmake/TimeShield @@ -27,8 +22,4 @@ vcpkg_cmake_config_fixup( vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE") -file(REMOVE_RECURSE - "${CURRENT_PACKAGES_DIR}/debug/include" - "${CURRENT_PACKAGES_DIR}/debug/lib" - "${CURRENT_PACKAGES_DIR}/debug/share/${PORT}" -) +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug")