Skip to content

Enhance OpenCode harness, achieve 100% test coverage, fix bugs#15

Merged
kyaulabs-bot merged 19 commits into
developfrom
main
Jul 6, 2026
Merged

Enhance OpenCode harness, achieve 100% test coverage, fix bugs#15
kyaulabs-bot merged 19 commits into
developfrom
main

Conversation

@kyau

@kyau kyau commented Jul 6, 2026

Copy link
Copy Markdown
Member

This pull request introduces a comprehensive overhaul of the project's developer workflow, focusing on improving code quality, enforcing consistency, and automating validation for contributions. The changes include the addition and enhancement of Git hooks for pre-commit, pre-push, and post-checkout/merge actions, new scripts for hook installation and harness validation, a robust CI workflow, and stricter handling of file attributes. These updates are designed to catch issues early, automate routine checks, and ensure a higher standard for repository hygiene.

Git Hooks & Automation Enhancements:

  • Pre-commit hook improvements:
    The .github/hooks/pre-commit script now:

    • Runs PHP, SCSS, and JS linters only on staged files, with explicit exclusion of third-party directories.
    • Supports both local and global installations of php-cs-fixer.
    • Adds staged-source RCS headers automatically if missing, using comment syntax appropriate to each file type.
    • Detects and adapts to different gitleaks versions for secret scanning.
    • Improves ESLint and Stylelint invocations to only lint staged files.
  • New Git hooks for workflow consistency:

    • Added post-checkout and post-merge hooks to automatically update submodules after branch changes or merges.
      [1] [2]

    • Introduced a pre-push hook that warns users when pushing a single-commit branch, discouraging squash merges and promoting a transparent development history.

    • Updated RCS headers in existing hooks for consistency.
      [1] [2]

  • Scripted hook installation:

    • Added .github/scripts/install-hooks.sh to automate the installation and updating of all Git hooks in the repository, backing up any existing hooks.

Validation & Continuous Integration:

  • Harness validation script:

    • Introduced .github/scripts/validate-harness.sh to automatically validate the structure and frontmatter of skills, agents, and commands in .opencode/, check for duplicate names, enforce naming conventions, and verify cross-references.
  • New CI workflow:

    • Added .github/workflows/ci.yml to run on pushes and PRs, performing:
      • Dependency installation (PHP/Node)
      • Syntax checks, linting, and style checks
      • Harness validation
      • Automated tests with code coverage
      • Secret scanning (Gitleaks)
      • Commit message linting
      • Static analysis (Semgrep)
      • Automated Playwright browser setup for integration tests

Repository Consistency:

  • File attribute enforcement:
    • Updated .gitattributes to enforce LF line endings for text files and proper handling of binary files, ensuring consistency across platforms.

kyau added 19 commits July 2, 2026 01:34
32 new tests across 2 test files reach 81% line coverage:

aurora.inc.php (83.9% — was 23%):
- comment(): RCS version extraction, compute/syscall timing, vim modeline
  toggle via optional 3rd param
- version(): parsed RCS version string from file header
- __set/__get: array merging on repeated dns/css/preload assignments,
  first-set-on-empty behavior, retrieval via __get
- constructor: display_errors toggle (status=true/false), html flag,
  templateDir overlay fallback to aurora templates
- htmlHeader(): returns false when no variables set, replaces {{ title }}
  and {{ description }} placeholders, injects CSS <link> tags with
  sha512 SRI hashes and cache-busting ?v= query string, DNS prefetch and
  preconnect <link> tags, preload <link> tags with cdn prefix
- htmlFooter(): external JS <script> with async defer, file-based JS
  <script> with SRI hashes and defer, ES module <script type="module">
  with SRI hashes, bare </body></html> output when no scripts set
- testVariables(): lists all replaced scalar and array variables post-render
- exceptionHandler(): head-body separator insertion when code=1 and
  display_errors on, silent error_log fallback when display_errors off

sql.inc.php (81.7%):
- constructor: throws on null db param, handles PDO connection failure
  gracefully (pdo=null)
- query(): returns false when PDO is null
- setDatabase(): returns false when PDO is null, returns false on PDO
  exec exception with formatted error output
- handleException(): HTML error output with display_errors on (span.error,
  full trace), silent error_log when display_errors off
- procException: re-throws PDOException when $err=THROW_EXCEPTION

Three bugs fixed:
- aurora.inc.php: __get return type changed from ?string to mixed;
  empty() on array properties was returning nothing for empty arrays
  (broken by empty() treating [] as falsy); added explicit is_array()
  branch so empty arrays are still returned via __get
- sql.inc.php: handleException trace formatting used direct array
  access on $line['type'], $line['function'], $line['file'], $line['line']
  without null checks; replaced with ?? '' null coalesce operators

OpenCode coding harness:
- opencode.json: wires .opencode/docs/conventions.md and
  .opencode/docs/build-pipeline.md as core instructions; Plan mode
  restricted to read-only and audit agents
- 7 agents (.opencode/agents/): tdd (red→green→refactor), test-audit,
  code-review (ocr scan + diff), resolve-merge-conflicts, semgrep
  (SAST PHP/JS/secrets), debug (log inspection + targeted tests),
  docs-writer (PHPDoc + RCS headers)
- 6 skills (.opencode/skills/): audit-deps, aurora-page,
  conventional-commits, pest-browser, rcs-header, scss-mobile-first
- 2 slash commands (.opencode/commands/): build-assets (rebuild SCSS+JS),
  security (SAST scan + CVE audit)
- 5 convention docs (.opencode/docs/): build-pipeline, conventions,
  mocking, refactoring, tests
- AGENTS.md: rewritten from ~512-line embedded reference to ~100-line
  harness-pointer style — only stack, boundaries, and pointers to
  skills/docs remain
- CODING_HARNESS.md: full harness structure diagram and reference
  (agents, commands, built-in features, skills)
- .semgrepignore: excludes vendor, node_modules, aurora, generated assets

Other:
- cliff.toml: feat and patch split into separate changelog groups
  (Features + Patches); added [bump] config (features_always_bump_minor,
  breaking_always_bump_major=false, custom patch increment regex)
- README.md: removed commented-out ANSI logo line, normalized table
  header separators (|-----|→|---|)
…urce files

Add 25 tests covering defensive error paths in Aurora and SQLHandler
classes, bringing per-file coverage from ~82% to 100% across all three
metrics (lines, methods, classes).

aurora.inc.php (83.6% → 100%):
- invalid CDN directory, preload SRI hashes, DNS-not-configured
- CSS/JS/module hash failures, file-not-found exceptions
- htmlHeader render failure, external ES module scripts
- projectVersion file-not-found, feof, and fopen error paths
- phpSet ini_set failure, testVariables orphaned entry (reflection)
- render feof I/O error via custom errorfeof:// stream wrapper fixture

sql.inc.php (81.7% → 100%):
- query/setDatabase success with mock PDO, IGNORE_ERRORS branch
- query PDOException catch, settings.inc.php inclusion
- new test files: A0_SqlHandlerNoSettingsTest, Z_SqlHandlerSocketTest
- move SQL constants from file-level to beforeEach for ordering isolation

Tests: 40 → 65, assertions: 99 → 149
…gainst redefinition

Prevents "Constant already defined" warning in PHP 8.5 when the socket
test runs after SqlHandlerTest.php's beforeEach has already defined
these constants in the same process.
The test for "includes settings.inc.php when it exists" unconditionally
overwrote the repo-root `settings.inc.php` with `<?php ` via
file_put_contents, then permanently deleted it with unlink() in the
finally block. On a configured dev machine with real credentials at that
path, running the test suite irrecoverably destroyed local DB settings.

The behavior is already covered: `beforeEach` defines SQL_USER/SQL_PASSWD
and all other constants, exercising the "settings loaded" path for every
test in the file, and A0_SqlHandlerNoSettingsTest covers the missing-file
path. No coverage is lost by removal.

Updated the coding harness to match kyaulabs/template.

Closes #1

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
…d XSS

When display_errors=1, handleException() echoed exception message,
class, type, function, file, and line values into a <pre> block without
escaping. A PDO exception triggered by an attacker-influenced query
embeds the payload in the message, where it executed raw in the
visitor's browser.

Wrap all six dynamic values in htmlspecialchars().

Closes #2

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
When fopen() fails ($fd === false), execution fell through to
fclose($fd), causing a TypeError on PHP 8.x. The test masked this
by catching both ValueError and TypeError.

Move fclose($fd) inside the if ($fd) branch so it only runs when
the file was successfully opened. Drop TypeError from the test's
catch since the crash path no longer exists, and add an explicit
assertion on $version returning null.

Closes #3

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
…al commits

Replace the per-file RCS $KYAULabs: header parser in projectVersion()
with a SemVer-based version resolver. A new version.inc.php stores the
release version (updated by /release), and backend/version.php provides
a git describe fallback for development environments.

RCS headers are stripped from all source files. The pre-commit hook
regenerates them in canonical Format A (creation stamp only) when
source files are next committed.

BREAKING CHANGE: version() now returns SemVer strings (e.g. v0.0.0-dev)
instead of RCS date strings. comment() output changes from RCS-style to
"Aurora vX.Y.Z  compute:Nms  syscall:Nms".

Closes #4

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
The three-branch is_array/empty guard in __get() treated empty
(but valid) array properties the same as missing properties,
triggering an E_USER_WARNING and returning null. Every whitelisted
property has a declared default, so the guard is unnecessary.
Returned to a simple unconditional read for whitelisted properties.

Closes #5

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
…cess

The "throws when SQL_USER is not defined" test relied on the `A0_` filename
prefix sorting before files whose beforeEach defines SQL_USER process-wide.
Random test order, explicit ordering, or a configured checkout would cause the
constructor not to throw, making the test fail.

Adding `@runInSeparateProcess` with `@preserveGlobalState disabled` ensures
the test runs in a true clean process where SQL_USER is never defined by
sibling test files.

Closes #6

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
Prevents PHP constant-redefinition warnings and cross-test pollution
when SQL_SOCKET is already set by real settings or `--repeat` runs,
matching the guarded pattern used for SQL_USER and SQL_PASSWD.

Closes #7

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
Store the validated CDN base path (computed from debug_backtrace() in
the constructor) and use it in htmlPreload() instead of the CWD-relative
'..' . $this->aurora_cdn . $url concatenation. Also removes all chdir()
guards from the test suite and anchors SRI test asset paths to __DIR__.

Closes #8

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
git-cliff silently drops this key — it does not exist in the [bump]
section spec. patch: commits already bump PATCH by default (all
non-breaking, non-feat commits do), so no replacement config is needed.

Closes #9

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
…ndleException

Add per-frame defaults via $line += [...] to eliminate scattered ?? ''
guards in both the HTML and error_log branches. Reuse the cached
$trace in the error_log loop instead of calling $e->getTrace() again.
Fix duplicate file/line output in error_log messages.

Closes #10

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
Runs on push to main/develop and pull requests. Jobs: PHP syntax
check, harness validation, php-cs-fixer, stylelint, eslint, Pest with
80% coverage floor, Semgrep SAST, Gitleaks, and commitlint for PRs.
Timeout at 15 minutes, PHP 8.5 + pcov, Node LTS.

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
validate-harness.sh checks .opencode/ skills, agents, and commands
for valid frontmatter, required fields, name consistency, duplicate
names, and cross-reference integrity. install-hooks.sh symlinks
.github/hooks into .git/hooks after a fresh clone.

Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
Bring coding harness (agents, skills, commands, evals, ADRs,
Semgrep rules, CI workflow, pre-commit hooks, and bootstrap docs)
up to parity with the template repository.

Plan-by: glm-5.2
Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
Add four-tier smoke tests (Unit, Feature, Integration, Browser)
plus browser test fixture. Add arch tests to Pest.php and Browser
testsuite to phpunit.xml. Exclude aurora submodule from coverage.

Plan-by: glm-5.2
Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
Add 12 positive/negative PHP fixtures for all six first-party
Semgrep rules. Add RulesPackTest that validates every rule
against its fixtures using the Semgrep CLI.

Plan-by: glm-5.2
Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
The constructor unconditionally called ini_set('display_errors', '1')
and related overrides at the top of __construct(), 40 lines before the
$status gate. Any AuroraException thrown during validation (missing
template, invalid CDN directory) was rendered verbosely with stack
traces and absolute paths to visitors even when $status=false.

Move error-display configuration to the top: safe defaults (display
OFF) first, then a $status-gated override before any validation that
may throw. Remove the redundant gate that was previously positioned
after the validation block.

Also correct the misleading `private $status = true` property default
to `false` (dead code, always overwritten by the constructor), and
replace the ternary-as-statement `($html) ? $this->html = $html : ''`
with `$this->html = $html`.

Fixes #11
Plan-by: glm-5.2
Acked-by: deepseek-v4-pro
Signed-off-by: kyau <git@kyaulabs.com>
@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@kyaulabs-bot kyaulabs-bot merged commit d8a11d6 into develop Jul 6, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants